diff options
author | William R. Otte <wotte@dre.vanderbilt.edu> | 2006-07-24 15:50:21 +0000 |
---|---|---|
committer | William R. Otte <wotte@dre.vanderbilt.edu> | 2006-07-24 15:50:21 +0000 |
commit | 3aff90f4a822fcf5d902bbfbcc9fa931d6191a8c (patch) | |
tree | 197c810e5f5bce17b1233a7cb8d7b50c0bcd25e2 /TAO/docs/pluggable_protocols | |
parent | 6b846cf03c0bcbd8c276cb0af61a181e5f98eaae (diff) | |
download | ATCD-3aff90f4a822fcf5d902bbfbcc9fa931d6191a8c.tar.gz |
Repo restructuring
Diffstat (limited to 'TAO/docs/pluggable_protocols')
-rw-r--r-- | TAO/docs/pluggable_protocols/cross_ref_motif.png | bin | 0 -> 147 bytes | |||
-rw-r--r-- | TAO/docs/pluggable_protocols/img1.png | bin | 0 -> 27555 bytes | |||
-rw-r--r-- | TAO/docs/pluggable_protocols/img2.png | bin | 0 -> 15874 bytes | |||
-rw-r--r-- | TAO/docs/pluggable_protocols/img3.png | bin | 0 -> 18831 bytes | |||
-rw-r--r-- | TAO/docs/pluggable_protocols/img4.png | bin | 0 -> 18899 bytes | |||
-rw-r--r-- | TAO/docs/pluggable_protocols/img5.png | bin | 0 -> 23267 bytes | |||
-rw-r--r-- | TAO/docs/pluggable_protocols/index.html | 2997 | ||||
-rw-r--r-- | TAO/docs/pluggable_protocols/pluggable_protocols.css | 31 |
8 files changed, 3028 insertions, 0 deletions
diff --git a/TAO/docs/pluggable_protocols/cross_ref_motif.png b/TAO/docs/pluggable_protocols/cross_ref_motif.png Binary files differnew file mode 100644 index 00000000000..7dd2dddf5ac --- /dev/null +++ b/TAO/docs/pluggable_protocols/cross_ref_motif.png diff --git a/TAO/docs/pluggable_protocols/img1.png b/TAO/docs/pluggable_protocols/img1.png Binary files differnew file mode 100644 index 00000000000..5899eb18c0b --- /dev/null +++ b/TAO/docs/pluggable_protocols/img1.png diff --git a/TAO/docs/pluggable_protocols/img2.png b/TAO/docs/pluggable_protocols/img2.png Binary files differnew file mode 100644 index 00000000000..1ddb28513a5 --- /dev/null +++ b/TAO/docs/pluggable_protocols/img2.png diff --git a/TAO/docs/pluggable_protocols/img3.png b/TAO/docs/pluggable_protocols/img3.png Binary files differnew file mode 100644 index 00000000000..c80c7edf6a8 --- /dev/null +++ b/TAO/docs/pluggable_protocols/img3.png diff --git a/TAO/docs/pluggable_protocols/img4.png b/TAO/docs/pluggable_protocols/img4.png Binary files differnew file mode 100644 index 00000000000..8eab370af23 --- /dev/null +++ b/TAO/docs/pluggable_protocols/img4.png diff --git a/TAO/docs/pluggable_protocols/img5.png b/TAO/docs/pluggable_protocols/img5.png Binary files differnew file mode 100644 index 00000000000..8cf1e2ca8ab --- /dev/null +++ b/TAO/docs/pluggable_protocols/img5.png diff --git a/TAO/docs/pluggable_protocols/index.html b/TAO/docs/pluggable_protocols/index.html new file mode 100644 index 00000000000..21fc5208a62 --- /dev/null +++ b/TAO/docs/pluggable_protocols/index.html @@ -0,0 +1,2997 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> + +<!-- $Id$ --> + +<HTML> +<HEAD> +<TITLE>Implementing Pluggable Protocols for TAO</TITLE> + +<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> +<META HTTP-EQUIV="Content-Style-Type" CONTENT="text/css"> + +<LINK REL="STYLESHEET" HREF="pluggable_protocols.css"> + +</HEAD> + +<BODY TEXT = "#000000" LINK="#000fff" VLINK="#ff0f0f" BGCOLOR="#ffffff"> + +<P> + +<H1 ALIGN="CENTER">Implementing Pluggable Protocols for TAO</H1> +<P ALIGN="CENTER"> +<STRONG> +<A HREF="http://www.cs.wustl.edu/~fredk/">Fred Kuhns</A>, +<A HREF="http://www.ece.uci.edu/~schmidt/">Douglas C. Schmidt</A>, +<A HREF="http://doc.ece.uci.edu/~coryan">Carlos O'Ryan</A>, +<A HREF="http://www.ece.uci.edu/~ossama/">Ossama Othman</A>, +and <A HREF="mailto:BTRASK@contactsystems.com">Bruce Trask</A> +</STRONG> +</P> + +<P ALIGN="CENTER"> +Center for Distributed Object Computing<BR> +Washington University at St.Louis +</P> + +<HR> + +<P> +<H3>Overview</H3><P> + +To be an effective platform for performance-sensitive real-time and +embedded applications, off-the-shelf CORBA middleware must preserve +the communication-layer quality of service (QoS) properties of +applications end-to-end. However, the standard CORBA GIOP/IIOP +interoperability protocols are not well suited for applications that +cannot tolerate the message footprint size, latency, and jitter +associated with general-purpose messaging and transport protocols. +Fortunately, the CORBA specification defines the notion of +"Environmentally-Specific Inter-ORB Protocols" (ESIOPs) that can be +used to integrate non-GIOP/IIOP protocols beneath an ORB. <P> + +To allow end-users and developers to take advantage of ESIOP +capabilities, it is useful for an ORB to support a <EM>pluggable +protocols framework</em> that allows custom messaging and transport +protocols to be configured flexibly and used transparently by +applications. This document explains how to develop pluggable +protocols using TAO's pluggable protocols framework. Here are some +links that describe TAO's pluggable protocols framework, though not +how to implement one: <BLOCKQUOTE> <A +HREF="../releasenotes/index.html#pp">../releasenotes/index.html#pp</A><BR> + +<A HREF="http://www.cs.wustl.edu/~schmidt/PDF/PfHSN.pdf">http://www.cs.wustl.edu/~schmidt/PDF/PfHSN.pdf</A><BR> +<A +HREF="http://www.cs.wustl.edu/~schmidt/PDF/pluggable_protocols.pdf">http://www.cs.wustl.edu/~schmidt/PDF/pluggable_protocols.pdf</A> +</BLOCKQUOTE> + +<P> +<HR> +<H3>Table of Contents</H3><P> +<UL> +<LI><A NAME="TOC_SECTION100" HREF="#SECTION100">Overview of Implementation of Pluggable Protocols for TAO</A> +<UL> +<LI><A NAME="TOC_SECTION110" HREF="#SECTION110">The Hard Way</A> +<LI><A NAME="TOC_SECTION120" HREF="#SECTION120">The Path of Least Resistance</A> +<UL> +<LI><A NAME="TOC_SECTION121" HREF="#SECTION121">Basic Requirements</A> +<LI><A NAME="TOC_SECTION122" HREF="#SECTION122">Basics of Implementing a Pluggable Protocol for TAO</A> +</UL> +</UL> +<LI><A NAME="TOC_SECTION200" HREF="#SECTION200">Pluggable Protocol Framework Components</A> +<UL> +<LI><A NAME="TOC_SECTION210" HREF="#SECTION210">The <TT>Acceptor</TT></A> +<UL> +<LI><A NAME="TOC_SECTION211" HREF="#SECTION211">Context</A> +<LI><A NAME="TOC_SECTION212" HREF="#SECTION212">Problem</A> +<LI><A NAME="TOC_SECTION213" HREF="#SECTION213">Solution</A> +<LI><A NAME="TOC_SECTION214" HREF="#SECTION214">Applying the solution to TAO</A> +<LI><A NAME="TOC_SECTION215" HREF="#SECTION215"><TT>Acceptor</TT> Implementation</A> +</UL> +<LI><A NAME="TOC_SECTION220" HREF="#SECTION220">The <TT>Connector</TT></A> +<UL> +<LI><A NAME="TOC_SECTION221" HREF="#SECTION221">Context</A> +<LI><A NAME="TOC_SECTION222" HREF="#SECTION222">Problem</A> +<LI><A NAME="TOC_SECTION223" HREF="#SECTION223">Solution</A> +<LI><A NAME="TOC_SECTION224" HREF="#SECTION224">Applying the solution in TAO</A> +<LI><A NAME="TOC_SECTION225" HREF="#SECTION225"><TT>Connector</TT> Implementation</A> +</UL> +<LI><A NAME="TOC_SECTION230" HREF="#SECTION230">The <TT>Profile</TT> Object</A> +<LI><A NAME="TOC_SECTION240" HREF="#SECTION240">The <TT>Protocol_Factory</TT> Object</A> +<LI><A NAME="TOC_SECTION250" HREF="#SECTION250">The <TT>Transport</TT> Object</A> +<UL> +<LI><A NAME="TOC_SECTION251" HREF="#SECTION251">Context</A> +<LI><A NAME="TOC_SECTION252" HREF="#SECTION252">Problem</A> +<LI><A NAME="TOC_SECTION253" HREF="#SECTION253">Solution</A> +<LI><A NAME="TOC_SECTION254" HREF="#SECTION254">Applying the solution in TAO</A> +<LI><A NAME="TOC_SECTION255" HREF="#SECTION255"><TT>Transport</TT> Implementation</A> +</UL> +<LI><A NAME="TOC_SECTION260" HREF="#SECTION260">The <TT>Connection_Handler</TT></A></LI> +<UL> +<LI><A NAME="TOC_SECTION261" HREF="#SECTION261"><TT>Connection_Handler</TT> Implementation</A></LI> +</UL> +</UL> +<LI><A NAME="TOC_SECTION300" HREF="#SECTION300">Notes From a ``Real World'' Pluggable Protocol Implementation</A> +<LI><A NAME="TOC_SECTION400" HREF="#SECTION400">Additional Implementation Information</A> +<UL> +<LI><A NAME="TOC_SECTION410" HREF="#SECTION410">Tags</A></LI> +</UL> +<LI><A NAME="TOC_SECTION500" HREF="#SECTION500">Using a Pluggable Protocol</A> +<LI><A NAME="TOC_SECTION600" HREF="#SECTION600">Bibliography</A> +</UL> +<!-- End of Table of Contents --> +<BR><HR> + + +<P> + +<H3><A NAME="SECTION100" HREF="#TOC_SECTION100"> +Overview of Implementation of Pluggable Protocols for TAO</A> +</H3> + +<P> +There are several basic implementation details that should be followed when +implementing pluggable protocols for +<A HREF="http://www.cs.wustl.edu/~schmidt/TAO.html">TAO</A>. This +section describes them. + +<P> + +<H3><A NAME="SECTION110" HREF="#TOC_SECTION110"> +The Hard Way</A> +</H3> + +<P> +It is possible to implement a pluggable protocol for TAO without using +any <A HREF="http://www.cs.wustl.edu/~schmidt/ACE.html">ACE</A> +components, or using existing pluggable protocols as a reference, but that is +certainly more difficult than taking advantage of the code reuse offered by +using existing ACE and TAO models and implementations. + +<P> + +<H3><A NAME="SECTION120" HREF="#TOC_SECTION120"> +The Path of Least Resistance</A> +</H3> + +<P> +TAO takes advantage of the many useful encapsulations provided by ACE. These +include ACE's <TT>IPC_SAP</TT> classes, <TT>Event Handlers</TT> and the operation +dispatching features provided by the <TT>Reactor</TT>. However, in order to +use these encapsulations some requirements must be satisfied. + +<P> + +<H3><A NAME="SECTION121" HREF="#TOC_SECTION121"> +Basic Requirements</A> +</H3> + +<P> +To be able to successfully use the ACE components listed above, the underlying +protocol used in the pluggable protocol for TAO should support the following +features and characteristics: + +<P> + +<UL> +<LI>Access to a session/connection via some type of handle (e.g. a UNIX file descriptor +or a Win32 <TT>HANDLE</TT>).</LI> +<LI>The ability to multiplex I/O using the <TT>select</TT> system call, or on Win32 +platforms, the <TT>WaitForMultipleObjects</TT> call on the handles that refer +to the open sessions/connections. This ability is required in order to use the +<TT>ACE_Select_Reactor</TT> or the <TT>ACE_WFMO_Reactor</TT> concrete <TT>Reactor</TT> +implementations. + +<P> +Some underlying transports do not provide any such ability. However, it may +sometimes be possible to separate data delivery from notification. For example, +TAO's shared memory transport transports data through shared memory, but since +it is not possible to use <TT>select</TT> on shared memory another mechanism +must be used for notification. One way to do this is to use a local IPC connection +strictly for notification purposes. Whenever, data is sent through shared memory, +a byte of data could be written to the local IPC connection. That local IPC +connection would be used to notify the receiving process that data is available +for reading in shared memory. Since local IPC can be multiplexed using the <TT>select</TT> +system call, the <TT>ACE_Select_Reactor</TT> can be used to handle operation +dispatching for the shared memory pluggable protocol. + +<P> + </LI> +<LI>A pluggable protocol should sit on top of lower-level implementation. The underlying +protocol implementation should not rely on any resources/features that are at +a similar or higher layer of abstraction than the pluggable protocol. For example, +if the underlying protocol needs to use Win32 resources/features such as <TT>HANDLE</TT>s +to hidden windows or the use of a window message pump then the underlying pluggable +protocol may be difficult or pointless to implement as a pluggable protocol.</LI> +</UL> + +<P> + +<H3><A NAME="SECTION122" HREF="#TOC_SECTION122"> +Basics of Implementing a Pluggable Protocol for TAO</A> +</H3> + +<P> +One of the easiest ways to implement a pluggable protocol for TAO is to do the +following: + +<P> + +<OL> +<LI>Implement ACE <TT>IPC_SAP</TT> wrappers around the underlying protocol implementation. +For example, ACE wraps the <I>socket</I> API to create an <TT>ACE_INET_Addr</TT>, +<TT>ACE_SOCK_Acceptor</TT>, <TT>ACE_SOCK_Connector</TT> and <TT>ACE_SOCK_Stream</TT>. +<TT>IPC_SAP</TT> wrappers for other implementations, such as OSI transport +protocol layer 4, aka <I>TP4</I>, should be implemented similarly. A TP4 implementation +could have an <TT>ACE_TP4_Addr</TT>, <TT>ACE_TP4_Acceptor</TT>, <TT>ACE_TP4_Connector</TT> +and an <TT>ACE_TP4_Stream</TT>. Any new implementation should retain the interface +provided by the base <TT>IPC_SAP</TT> classes in ACE.</LI> <P> + +<LI>Once the above ACE <TT>IPC_SAP</TT> components have been implemented, creating +the necessary TAO pluggable protocol components should be fairly easy. In fact, +much of the code can be ``cut and pasted'' from existing TAO pluggable protocol +implementations. For example, TAO's UIOP pluggable protocol was, for the most +part, based entirely on the IIOP pluggable protocol code found in TAO's ``tao/IIOP_*'' +source files. The only things that had to be changed for UIOP were the protocol +prefix, address format and URL style IOR format. Each of these pluggable protocol +characteristics is documented later in this documentation.</LI> +</OL> + +<P> + +The next section goes into detail about TAO's pluggable protocol +framework components and their public interfaces. It is our goal that +no changes to ACE or TAO should be necessary to implement a pluggable +protocol. Naturally, as with all frameworks, it's only possible to +achieve this goal if (1) all possible use-cases are understood in +advance or (2) the framework is generalized when confronted with new +use-cases that weren't handled before. Therefore, we describe the +conditions that must currently hold in order to develop and integrate +a pluggable protocol for TAO. +<P> +<HR> +<P> +<H3><A NAME="SECTION200" HREF="#TOC_SECTION200"> +Pluggable Protocol Framework Components</A> +</H3> + +<P> +In order for a pluggable protocol to be usable by TAO <STRONG><EM>without</EM></STRONG> making any modifications +to TAO itself, it must be implemented to provide the functionality dictated +by TAO's pluggable protocols framework interface. This functionality is implemented +within several components, namely the <TT>Acceptor</TT>, <TT>Connector</TT>, +<TT>Connection Handler</TT>, <TT>Protocol Factory</TT>, <TT>Profile</TT> and +<TT>Transport</TT>. This section describes each of them. + +<P> + +<H3><A NAME="SECTION210" HREF="#TOC_SECTION210"> +The <TT>Acceptor</TT></A> +</H3> + +<P> + +<A NAME="design:accept"></A> +<P> + +<H3><A NAME="SECTION211" HREF="#TOC_SECTION211"> +Context</A> +</H3> + +<P> +A server can accept connections at one or more endpoints, potentially using +the same protocol for all endpoints. The set of protocols that an ORB uses to +play the client role need not match the set of protocols used for the server +role. Moreover, the ORB can even be a ``pure client,'' <I>i.e.</I>, a client +that only makes requests, in which case it can use several protocols to make +requests, but receive no requests from other clients. + +<P> + +<H3><A NAME="SECTION212" HREF="#TOC_SECTION212"> +Problem</A> +</H3> + +<P> +The server must generate an IOR that includes all possible inter-ORB and transport-protocol-specific +profiles for which the object can be accessed. As with the client, it should +be possible to add new protocols without changing the ORB. + +<P> + +<H3><A NAME="SECTION213" HREF="#TOC_SECTION213"> +Solution</A> +</H3> + +<P> +We use the Acceptor pattern [<A + HREF="#Schmidt:97c">1</A>] to accept the connections. As +with the Connector pattern, an Acceptor decouples the connection establishment +from the processing performed on that connection. However, in the Acceptor pattern, +the connection is accepted <I>passively</I>, rather than being initiated <I>actively</I>. + +<P> + +<H3><A NAME="SECTION214" HREF="#TOC_SECTION214"> +Applying the solution to TAO</A> +</H3> + +<P> +Figure <A HREF="#server">1</A> illustrates how TAO's pluggable protocols framework leverages +the design presented in Section <A HREF="#design:transparent"><IMG ALIGN="BOTTOM" BORDER="1" ALT="[*]" + SRC="cross_ref_motif.png"></A>. The concrete ACE +<TT>Service Handler</TT> created by the ACE <TT>Acceptor</TT> is responsible +for implementing the External Polymorphism pattern [<A HREF="#Schmidt:97e">2</A>] and encapsulating itself +behind the <TT>Transport</TT> interface defined in our pluggable protocols framework. + +<P> + +<P></P> +<DIV ALIGN="CENTER"><A NAME="server"></A><A NAME="683"></A> +<TABLE> +<CAPTION ALIGN="BOTTOM"><STRONG>Figure 1:</STRONG> +Server Pluggable Protocol Class Diagram</CAPTION> +<TR><TD><P> + +<P> + +<DIV ALIGN="CENTER"> +<!-- MATH + $\resizebox* {5in}{!}{\includegraphics{graphics/server.eps}}$ + --> +<IMG + WIDTH="561" HEIGHT="634" ALIGN="BOTTOM" BORDER="0" + SRC="img1.png" + ALT="Server"> </DIV> +<P> +<DIV ALIGN="CENTER"></DIV></TD></TR> +</TABLE> +</DIV><P></P> + +<P> +As discussed in Section <A HREF="#design:adapt"><IMG ALIGN="BOTTOM" BORDER="1" ALT="[*]" + SRC="cross_ref_motif.png"></A>, we use the Adapter pattern to leverage +the ACE implementation of the Acceptors. This pattern also permits a seamless +integration with the lower levels of the ORB. In the Acceptor pattern, the <TT>Acceptor</TT> +object is a factory that creates <TT>Service Handler</TT>s. <TT>Service +Handler</TT>s are responsible for performing I/O with their connected peers. In +TAO's pluggable protocol framework, the <TT>Transport</TT> objects are <TT>Service +Handlers</TT> implemented as abstract classes. This design shields the ORB from +variations in the <TT>Acceptor</TT>s, <TT>Connector</TT>s, and <TT>Service +Handler</TT>s for each particular protocol. + +<P> +When a connection is established, the concrete <TT>Acceptor</TT> creates the +appropriate <TT>Connection Handler</TT> and IOP objects. The <TT>Connection +Handler</TT> also creates a <TT>Transport</TT> object that functions as a bridge. +As with the <TT>Connector</TT>, the <TT>Acceptor</TT> also acts as a bridge +object, hiding the transport- and strategy-specific details of the acceptor. + +<P> + +<H3><A NAME="SECTION215" HREF="#TOC_SECTION215"> +<TT>Acceptor</TT> Implementation</A> +</H3> + +<P> +TAO's <TT>Acceptor</TT> interface, shown below, is declared in the file +<TT><<A HREF="../../tao/Transport_Acceptor.h">tao/Transport_Acceptor.h</A>></TT>. +All <TT>Acceptor</TT> implementations must inherit from the <TT>TAO_Acceptor</TT> +abstract base class. + +<P> + +<DL COMPACT> +<DT> +<DD>class TAO_Export TAO_Acceptor<BR> +{<BR> + // = TITLE<BR> + // Abstract Acceptor class used for pluggable protocols.<BR> + //<BR> + // = DESCRIPTION<BR> + // Base class for the Acceptor bridge calls.<BR> +public:<BR> + TAO_Acceptor (CORBA::ULong tag);<BR> + + +<BR> + + virtual ~TAO_Acceptor (void); + +<BR> + + // Destructor + +<BR> + + + +<BR> + + CORBA::ULong tag (void) const; + +<BR> + + // The tag, each concrete class will have a specific tag value. + +<BR> + + + +<BR> + + CORBA::Short priority (void) const; + +<BR> + + // The priority for this endpoint. + +<BR> + + + +<BR> + + virtual int open (TAO_ORB_Core *orb_core, + +<BR> + + int version_major, + +<BR> + + int version_minor, + +<BR> + + const char *address, + +<BR> + + const char *options = 0) = 0; + +<BR> + + // Method to initialize acceptor for address. + +<BR> + + + +<BR> + + virtual int open_default (TAO_ORB_Core *orb_core, + +<BR> + + const char *options = 0) = 0; + +<BR> + + // Open an acceptor on the default endpoint for this protocol + +<BR> + + + +<BR> + + virtual int close (void) = 0; + +<BR> + + // Closes the acceptor + +<BR> + + + +<BR> + + virtual int create_mprofile (const TAO_ObjectKey &object_key, + +<BR> + + TAO_MProfile &mprofile) = 0; + +<BR> + + // Create the corresponding profile for this endpoint. + +<BR> + + + +<BR> + + virtual int is_collocated (const TAO_Profile* profile) = 0; + +<BR> + + // Return 1 if the <profile> has the same endpoint as the acceptor. + +<BR> + + + +<BR> + + virtual CORBA::ULong endpoint_count (void) = 0; + +<BR> + + // Returns the number of endpoints this acceptor is listening on. This + +<BR> + + // is used for determining how many profiles will be generated + +<BR> + + // for this acceptor. + +<BR> + + + +<BR> +protected: + +<BR> + + CORBA::Short priority_; + +<BR> + + // The priority for this endpoint + +<BR> + + + +<BR> +private: + +<BR> + + CORBA::ULong tag_; + +<BR> + + // IOP protocol tag. + +<BR> + + + +<BR> + +}; + + </DD> +</DL> +A description of each of the methods that must be implemented follows: + +<P> + +<DL> +<DT><STRONG>The Constructor.</STRONG></DT> +<DD>Other than initializing members of a pluggable protocol <TT>Acceptor</TT> +implementation, nothing else is really done in the constructor. For example, +the <TT>TAO_IIOP_Acceptor</TT> constructor implementation is: +<P> + +<DL COMPACT> +<DT> +<DD>TAO_IIOP_Acceptor::TAO_IIOP_Acceptor (void)<BR> +<DD> : TAO_Acceptor (TAO_TAG_IIOP_PROFILE), + +<BR> + + version_ (TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR), + +<BR> + + orb_core_ (0), + +<BR> + + base_acceptor_ (), + +<BR> + + creation_strategy_ (0), + +<BR> + + concurrency_strategy_ (0), + +<BR> + + accept_strategy_ (0) + +<BR> + +{ + +<BR> + +}</DD> +</DL> +<P> +Note that initializing the <TT>TAO_Acceptor</TT> base class with a +<I>tag</I> value is required. Additional information about tags is +available in the +<A HREF="#SECTION410">tags section</A> +of this document. In this case, +<TT>TAO_TAG_IIOP_PROFILE</TT> is defined to be the OMG assigned tag +for the CORBA IIOP protocol. Until a tag that uniquely +identifies the protocol is assigned, a tag value that isn't +used by any other protocol can be used in the meantime. +</DL> + +<P> +<DL> +<DT><STRONG><TT><A NAME="TAO_Acceptor::open">open</A></TT>.</STRONG></DT> +<DD>The <TT>open</TT> method initializes the acceptor, i.e. sets +the protocol version to use (if supported), parses any protocol-specific options +(if any) and creates the endpoint passed to it. +<P> +The address specified by using the <TT><A HREF="../Options.html#-ORBEndpoint">-ORBEndpoint</A></TT> ORB option is passed +directly to this method. If more than one address is specified within a given +<TT>-ORBEndpoint</TT> option then each address is passed one by one to this +method by the pluggable protocols framework. For example, the following <TT>-ORBEndpoint</TT> +command line option: + +<P> + +<DL COMPACT> +<DT> +<DD>-ORBEndpoint iiop://1.1@foo.xyz.com,1.0@bar.abc.com</DD> +</DL> +<P> +will cause the following <TT>open</TT> method invocations to occur: + +<P> + +<DL COMPACT> +<DT> +<DD>open (orb_core, 1, 1, "foo.xyz.com", 0)<BR> +open (orb_core, 1, 0, "bar.abc.com", 0)</DD> +</DL> +<P> +Extracting individual addresses from an <TT>-ORBEndpoint</TT> option is handled +by TAO's pluggable protocols framework. It is up to the pluggable protocol to +handle the address passed to this method. + +<P> + </DD> +<DT><STRONG><TT><A NAME="TAO_Acceptor::open_default">open_default</A></TT>.</STRONG></DT> +<DD>Each pluggable protocol should have the ability to +open a default endpoint. For example, it should be possible to make the pluggable +protocol open an endpoint without specifying an address, in which case an address +is chosen by the pluggable protocol. This method is invoked when <TT>-ORBEndpoint</TT> +options such as the following are used: + +<P> + +<DL COMPACT> +<DT> +<DD>-ORBEndpoint iiop://</DD> +</DL> +<P>In this case, an IIOP endpoint will be created on the local host. The port will +be chosen by the IIOP pluggable protocol. <TT>open_default</TT> will invoked +in the following manner: + +<P> + +<DL COMPACT> +<DT> +<DD><TT>open_default (orbcore, 0)</TT></DD> +</DL></DD> +<P> +<DT><STRONG><TT>close</TT>.</STRONG></DT> +<DD>The <TT>close</TT> method is self-explanatory. It simply shuts +down any open endpoints, and recovers resources as necessary. This method is +automatically invoked by the pluggable protocols framework when the ORB associated +with that endpoint is shut down.</DD> +<P> +<DT><STRONG><TT>create_mprofile</TT>.</STRONG></DT> +<DD>The <TT>create_mprofile</TT> method creates a protocol-specific +<TT>Profile</TT> object and gives ownership of that profile to the <TT>TAO_MProfile</TT> +object, basically a container that holds multiple profiles, passed to it. The +code for this method is typically ``boilerplate,'' i.e. it can be based almost +entirely on TAO's existing pluggable protocol implementations of <TT>create_profile</TT>. +Here is how it is implemented in TAO's IIOP acceptor: + +<P> + +<DL COMPACT> +<DT> +<DD>int<BR> +TAO_IIOP_Acceptor::create_mprofile (const TAO_ObjectKey &object_key, <BR> +TAO_MProfile &mprofile) +<BR> +{ +<BR> + // @@ we only make one for now +<BR> + int count = mprofile.profile_count (); +<BR> + if ((mprofile.size () - count) < 1 +<BR> + && mprofile.grow (count + 1) == -1) +<BR> + return -1; +<BR> + +<BR> + TAO_IIOP_Profile *pfile = 0; +<BR> + ACE_NEW_RETURN (pfile, +<BR> + TAO_IIOP_Profile (this->host_.c_str (), +<BR> + this->address_.get_port_number (), +<BR> + object_key, +<BR> + this->address_, +<BR> + this->version_, +<BR> + this->orb_core_), +<BR> + -1); +<BR> + +<BR> + if (mprofile.give_profile (pfile) == -1) +<BR> + { +<BR> + pfile->_decr_refcnt (); +<BR> + pfile = 0; +<BR> + return -1; +<BR> + } +<BR> + +<BR> + if (this->orb_core_->orb_params ()->std_profile_components () == 0) +<BR> + return 0; +<BR> + +<BR> + pfile->tagged_components ().set_orb_type (TAO_ORB_TYPE); +<BR> + +<BR> + CONV_FRAME::CodeSetComponentInfo code_set_info; +<BR> + code_set_info.ForCharData.native_code_set = +<BR> + TAO_DEFAULT_CHAR_CODESET_ID; +<BR> + code_set_info.ForWcharData.native_code_set = +<BR> + TAO_DEFAULT_WCHAR_CODESET_ID; +<BR> + pfile->tagged_components ().set_code_sets (code_set_info); +<BR> + +<BR> + pfile->tagged_components ().set_tao_priority (this->priority ()); +<BR> + +<BR> + return 0; + +<P> + +}</DD> +</DL> +<P> +Most of the code that is common to all pluggable protocols will be factored +out of this method in the near future. + +<P> + </DD> +<DT><STRONG><TT>is_collocated</TT>.</STRONG></DT> +<DD>The <TT>is_collocated</TT> method checks if the <TT>Profile</TT> +has the same endpoint as the <TT>Acceptor</TT>. Assuming ACE is used as the +underlying layer between the operating system calls and a pluggable protocol, +this code is also ``boilerplate.'' TAO's IIOP implementation does the following: + +<P> + +<DL COMPACT> +<DT> +<DD>int +<BR> +TAO_IIOP_Acceptor::is_collocated (const TAO_Profile *pfile) +<BR> +{ +<BR> + const TAO_IIOP_Profile *profile = +<BR> + ACE_dynamic_cast(const TAO_IIOP_Profile *, +<BR> + pfile); +<BR> + +<BR> + // compare the port and sin_addr (numeric host address) +<BR> + return profile->object_addr () == this->address_; +<BR> +}</DD> +</DL></DD> +<P> +<DT><STRONG><TT>endpoint_count</TT>.</STRONG></DT> +<DD><TT>endpoint_count</TT> returns the number of endpoints +the <TT>Acceptor</TT> is listening on. This is used for determining how many +<TT>Profiles</TT> will be generated for this <TT>Acceptor</TT>. Currently, all +of TAO's pluggable protocols simply return <TT>1</TT>.</DD> +</DL> + +<P> + +<H3><A NAME="SECTION220" HREF="#TOC_SECTION220"> +The <TT>Connector</TT></A> +</H3> + +<P> + +<A NAME="design:connect"></A> +<P> + +<H3><A NAME="SECTION221" HREF="#TOC_SECTION221"> +Context</A> +</H3> + +<P> +When a client references an object, the ORB must obtain the corresponding profile +list, which is derived from the IOR and a profile ordering policy, and transparently +establish a connection to the server. + +<P> + +<H3><A NAME="SECTION222" HREF="#TOC_SECTION222"> +Problem</A> +</H3> + +<P> +There can be one or more combinations of inter-ORB and transport protocols available +in an ORB. For a given profile, the ORB must verify the presence of the associated +IOP and transport protocol, if available. It must then locate the applicable +<TT>Connector</TT> and delegate it to establish the connection. + +<P> + +<H3><A NAME="SECTION223" HREF="#TOC_SECTION223"> +Solution</A> +</H3> + +<P> +We use the Connector pattern [<A + HREF="#Schmidt:97c">1</A>] to actively establish a connection +to a remote object. This pattern decouples the connection establishment from +the processing performed after the connection is successful. As before, the +<TT>Connector Registry</TT> shown in Figure <A HREF="#e2e">2</A> is used + +<P></P> +<DIV ALIGN="CENTER"><A NAME="e2e"></A><A NAME="184"></A> +<TABLE> +<CAPTION ALIGN="BOTTOM"><STRONG>Figure 2:</STRONG> +Connection Establishment Using Multiple Pluggable Protocols</CAPTION> +<TR><TD><P> + +<P> + +<P> + +<DIV ALIGN="CENTER"> +<!-- MATH + $\resizebox* {9cm}{!}{\includegraphics{graphics/pp_e2e.eps}}$ + --> +<IMG + WIDTH="405" HEIGHT="460" ALIGN="BOTTOM" BORDER="0" + SRC="img2.png" + ALT="pp_e2e"> </DIV> +<P> +<DIV ALIGN="CENTER"></DIV></TD></TR> +</TABLE> +</DIV><P></P> +to locate the right <TT>Connector</TT> for the current profile. The actual +profile selected for use will depend on the set of Policies active at the time +of connection establishment. However, once a profile is selected, the connector +registry matches the profile type, represented by a well known tag, with an +instance of a concrete <TT>Connector</TT>. + +<P> + +<H3><A NAME="SECTION224" HREF="#TOC_SECTION224"> +Applying the solution in TAO</A> +</H3> + +<P> +As described in Section <A HREF="#design:adapt"><IMG ALIGN="BOTTOM" BORDER="1" ALT="[*]" + SRC="cross_ref_motif.png"></A>, <TT>Connector</TT>s are adapters +for the ACE implementation of the Connector pattern. Thus, they are typically +lightweight objects that simply delegate to a corresponding ACE component. + +<P> +Figure <A HREF="#client">3</A> shows the base classes and their relations for IIOP. + +<P></P> +<DIV ALIGN="CENTER"><A NAME="client"></A><A NAME="688"></A> +<TABLE> +<CAPTION ALIGN="BOTTOM"><STRONG>Figure 3:</STRONG> +Client Pluggable Protocol Class Diagram</CAPTION> +<TR><TD><P> + +<P> + +<DIV ALIGN="CENTER"> +<!-- MATH + $\resizebox* {5in}{!}{\includegraphics{graphics/client.eps}}$ + --> +<IMG + WIDTH="563" HEIGHT="416" ALIGN="BOTTOM" BORDER="0" + SRC="img3.png" + ALT="Client"> </DIV> +<P> +<DIV ALIGN="CENTER"></DIV></TD></TR> +</TABLE> +</DIV><P></P> +This figure shows an explicit co-variance between the <TT>Profile</TT> and +the <TT>Connector</TT>s for each protocol. In general, a <TT>Connector</TT> +must downcast the <TT>Profile</TT> to its specific type. This downcast is safe +because profile creation is limited to the <TT>Connector</TT> and <TT>Acceptor</TT> +registries. In both cases, the profile is created with a matching tag. The tag +is used by the Connector Registry to choose the <TT>Connector</TT> that can +handle each profile. + +<P> +As shown in the same figure, the Connector Registry manipulates only the base +classes. Therefore, new protocols can be added without requiring any modification +to the existing pluggable protocols framework. When a connection is successfully +established, the <TT>Profile</TT> is passed a pointer to the particular IOP +object and to the <TT>Transport</TT> objects that were created. + +<P> + +<H3><A NAME="SECTION225" HREF="#TOC_SECTION225"> +<TT>Connector</TT> Implementation</A> +</H3> + +<P> +TAO's <TT>Connector</TT> interface, shown below, is declared in the file <TT>< +<A HREF="../../tao/Transport_Connector.h">tao/Transport_Connector.h</A>></TT>. +All <TT>Connector</TT> implementations must inherit from the <TT>TAO_Connector</TT> +abstract base class. + +<P> + +<DL COMPACT> +<DT> +<DD>class TAO_Export TAO_Connector +<BR> +{ +<BR> + // = TITLE +<BR> + // Generic Connector interface definitions. +<BR> + // +<BR> + // = DESCRIPTION +<BR> + // Base class for connector bridge object. +<BR> +public: +<BR> + +<BR> + TAO_Connector (CORBA::ULong tag); +<BR> + // default constructor. +<BR> + +<BR> + virtual ~TAO_Connector (void); +<BR> + // the destructor. +<BR> + +<BR> + CORBA::ULong tag (void) const; +<BR> + // The tag identifying the specific ORB transport layer protocol. +<BR> + // For example TAO_TAG_IIOP_PROFILE = 0. The tag is used in the +<BR> + // IOR to identify the type of profile included. IOR -> {{tag0, +<BR> + // profile0} {tag1, profole1} ...} GIOP.h defines typedef +<BR> + // CORBA::ULong TAO_IOP_Profile_ID; +<BR> + +<BR> + int make_mprofile (const char *ior, +<BR> + TAO_MProfile &mprofile, +<BR> + CORBA::Environment &ACE_TRY_ENV); +<BR> + // Parse a string containing a URL style IOR and return an +<BR> + // MProfile. +<BR> + +<BR> + virtual int open (TAO_ORB_Core *orb_core) = 0; +<BR> + // Initialize object and register with reactor. +<BR> + +<BR> + virtual int close (void) = 0; +<BR> + // Shutdown Connector bridge and concreate Connector. +<BR> + +<BR> + virtual int connect (TAO_Profile *profile, +<BR> + TAO_Transport *&, +<BR> + ACE_Time_Value *max_wait_time) = 0; +<BR> + // To support pluggable we need to abstract away the connect() +<BR> + // method so it can be called from the GIOP code independant of the +<BR> + // actual transport protocol in use. +<BR> + +<BR> + virtual int preconnect (const char *preconnections) = 0; +<BR> + // Initial set of connections to be established. +<BR> + +<BR> + virtual TAO_Profile *create_profile (TAO_InputCDR& cdr) = 0; +<BR> + // Create a profile for this protocol and initialize it based on the +<BR> + // encapsulation in <cdr> +<BR> + +<BR> + virtual int check_prefix (const char *endpoint) = 0; +<BR> + // Check that the prefix of the provided endpoint is valid for use +<BR> + // with a given pluggable protocol. +<BR> + +<BR> + virtual char object_key_delimiter (void) const = 0; +<BR> + // Return the object key delimiter to use or expect. +<BR> + +<BR> +#if defined (TAO_USES_ROBUST_CONNECTION_MGMT) +<BR> + virtual int purge_connections (void) = 0; +<BR> + // Purge "old" connections. +<BR> +#endif /* TAO_USES_ROBUST_CONNECTION_MGMT */ +<BR> + +<BR> +protected: +<BR> + virtual void make_profile (const char *endpoint, +<BR> + TAO_Profile *&, +<BR> + CORBA::Environment &ACE_TRY_ENV) = 0; +<BR> + // Create a profile with a given endpoint. +<BR> + +<BR> +private: +<BR> + CORBA::ULong tag_; +<BR> + // IOP protocol tag. +<BR> +};</DD> +</DL>A description of each of the methods that must be implemented follows: + +<P> + +<DL> +<DT><STRONG>The Constructor.</STRONG></DT> +<DD>As with the <TT>Acceptor</TT> constructor, the <TT>TAO_Connector</TT> +base class should be initialized with the tag associated with the pluggable +protocol in question. Here is TAO's IIOP pluggable protocol <TT>Connector</TT> +constructor: +<P> + +<DL COMPACT> +<DT> +<DD>TAO_IIOP_Connector::TAO_IIOP_Connector (void) +<BR> + : TAO_Connector (TAO_TAG_IIOP_PROFILE), +<BR> + orb_core_ (0), +<BR> + base_connector_ () +<BR> +{ +<BR> +}</DD> +</DL></DD> +<P> +<DT><STRONG><TT>open</TT>.</STRONG></DT> +<DD>The <TT>open</TT> method simply opens the underlying connector. +This is typically an <TT>ACE_Strategy_Connector</TT> template instance. For +example, TAO's IIOP pluggable protocol uses an + +<P> + +<DL COMPACT> +<DT> +<DD>ACE_Strategy_Connector<TAO_IIOP_Client_Connection_Handler, +<BR> + ACE_SOCK_CONNECTOR></DD> +</DL>as its underlying connection strategy. No connection establishment occurs here. +Note that, if ACE is used to implement a <TT>Connector</TT>, this method should +also register the <TT>Connection Handler</TT> with an <TT>ACE_Reactor</TT>. + +<P> + </DD> +<DT><STRONG><TT>close</TT>.</STRONG></DT> +<DD><TT>close</TT> simply closes the underlying <TT>Connector</TT> +bridge and the concrete <TT>Connector</TT>.</DD> +<P> +<DT><STRONG><TT>connect</TT>.</STRONG></DT> +<DD>The <TT>connect</TT> method actively establishes a connection +to the endpoint encoded within the IOR in use. It should first verify that the +tag contained within <TT>Profile</TT> passed to it matches the tag associated +with the pluggable protocol. If the tags do not match then an attempt use a +<TT>Profile</TT> for another pluggable protocol was made. + +<P> +The <TT>Transport</TT> object must also be set in this method. This is generally +done by using the <TT>transport</TT> method found within the <TT>Connection +Handler</TT> being used. + +<P> + </DD> +<DT><STRONG><TT>preconnect</TT>.</STRONG></DT> +<DD>The <TT>preconnect</TT> method is invoked when the <TT><A HREF="../Options.html#-ORBPreconnect">-ORBPreconnect</A></TT> +ORB option is used. It causes a blocking connection to be made to the specified +address. Multiple connections can be made to the same endpoint. For example, +the following <TT>-ORBPreconnect</TT> option will cause two IIOP blocking connections +to be made to the specified host and port: + +<P> + +<DL COMPACT> +<DT> +<DD>-ORBPreconnect iiop://foo.bar.com:1234,foo.bar.com:1234</DD> +</DL> +<P> +Much of the preconnect parsing code in TAO's current <TT>preconnect</TT> implementations +will be factored out into a common method. Pluggable protocols will still be +responsible for parsing addresses, just like the <TT>open</TT> method in <TT>Acceptor</TT>s +(not <TT>Connector</TT>s). + +<P> + </DD> +<DT><STRONG><TT>check_prefix</TT>.</STRONG></DT> +<DD><TT>check_prefix</TT> checks that the protocol prefix +in a URL style IOR or preconnect endpoint is valid for use with a given pluggable +protocol. For example, the <TT>check_prefix</TT> implementation in TAO's IIOP +pluggable protocol looks like the following: + +<P> + +<DL COMPACT> +<DT> +<DD>int +<BR> +TAO_IIOP_Connector::check_prefix (const char *endpoint) +<BR> +{ +<BR> + // Check for a valid string +<BR> + if (!endpoint || !*endpoint) +<BR> + return -1; // Failure +<BR> + +<BR> + const char *protocol[] = { "iiop", "iioploc" }; +<BR> + +<BR> + size_t slot = ACE_OS::strchr (endpoint, ':') - endpoint; +<BR> + +<BR> + size_t len0 = ACE_OS::strlen (protocol[0]); +<BR> + size_t len1 = ACE_OS::strlen (protocol[1]); +<BR> + +<BR> + // Check for the proper prefix in the IOR. If the proper prefix +<BR> + // isn't in the IOR then it is not an IOR we can use. +<BR> + if (slot == len0 +<BR> + && ACE_OS::strncasecmp (endpoint, protocol[0], len0) == 0) +<BR> + return 0; +<BR> + else if (slot == len1 +<BR> + && ACE_OS::strncasecmp (endpoint, protocol[1], len1) == 0) +<BR> + return 0; +<BR> + +<BR> + return -1; +<BR> + // Failure: not an IIOP IOR +<BR> + // DO NOT throw an exception here. +<BR> +}</DD> +</DL> +<P> +It checks that the protocol prefix in a URL style IOR (e.g. <TT>corbaloc:iiop:foo.bar.com:1234/...</TT>) +or preconnect endpoint matches the one(s) supported by the IIOP pluggable protocol, +in this case ``<TT>iiop</TT>'' and ``<TT>iioploc</TT>.'' If no match occurs +then return an error condition (<TT>-1</TT>). Note that the protocol prefix +``<TT>iiop</TT>'' is only there for backward compatibility. It may be removed +in future TAO releases. + +<P> +This method is important for TAO's implementation of the CORBA Interoperable +Naming Service. + +<P> + </DD> +<DT><STRONG><TT>object_key_delimiter</TT>.</STRONG></DT> +<DD>The object key delimiter within a URL style +IOR is the character that separates the address from the object key. For example, +in the following IIOP URL style IOR: + +<P> + +<DL COMPACT> +<DT> +<DD>corbaloc:iiop:1.1@foo.bar.com:1234/some_object_key</DD> +</DL> +<P> +the object key delimiter is `<TT>/</TT>.' However, this character is not suitable +for all pluggable protocols, such as TAO's UIOP pluggable protocol, because +addresses within a URL style IOR may contain that very same character. A typical +TAO UIOP URL style IOR may look something like: + +<P> + +<DL COMPACT> +<DT> +<DD>uioploc:///tmp/foobar|some_other_object_key</DD> +</DL> +<P> +In this case, the object key delimiter is a vertical bar `<TT>|</TT>' because +using the same object key delimiter that IIOP uses `<TT>/</TT>' would cause +the point where the UIOP rendezvous point ``<TT>/tmp/foobar</TT>'' ends and +where the object key ``<TT>some_other_object_key</TT>'' begins to be ambiguous. +For instance, if an IIOP object key delimiter was used in a UIOP URL style IOR +as follows: + +<P> + +<DL COMPACT> +<DT> +<DD>uioploc:///tmp/foobar/some_other_object_key</DD> +</DL> +<P> +it then becomes impossible to tell if the rendezous point is ``<TT>/tmp</TT>'' +or ``<TT>/tmp/foobar</TT>,'' and similarly for the object key, hence the need +for an object key delimiter other than `<TT>/</TT>.' + +<P> +In general, this method simply returns a static variable in the associated <TT>Profile</TT> +that contains the object key delimiter appropriate for the given pluggable protocol. + +<P> + </DD> +<DT><STRONG><TT>create_profile</TT>.</STRONG></DT> +<DD>This method creates and initializes a profile using +the provided CDR stream. Most of this code is also ``boilerblate.'' As such, +it may be factored out in future TAO releases.</DD> +<P> +<DT><STRONG><TT>make_profile</TT>.</STRONG></DT> +<DD><TT>make_profile</TT> is another method that can essentially +be ``cut and pasted'' from existing TAO pluggable protocols. It is simply +a <TT>Profile</TT> factory. The <TT>Profile</TT> it creates is initialized with +an object reference of the form: + +<P> + +<DL COMPACT> +<DT> +<DD>N.n@address/object_key</DD> +</DL> +<P> +or +<P> +<DL COMPACT> +<DT> +<DD>address/object_key</DD> +</DL> +<P> +where ``<TT>N.n</TT>'' are the major and minor protocol versions, respectively, +and the `<TT>/</TT>' is the protocol-specific object key delimiter. + +<P></DD> +</DL> + +<P> + +<H3><A NAME="SECTION230" HREF="#TOC_SECTION230"> +The <TT>Profile</TT> Object</A> +</H3> + +<P> +TAO <TT>Profile</TT> objects encapsulate all of the methods and members necessary +to create and parse a protocol-specific IOR, in addition to representing object +address and location information. TAO <TT>Profile</TT>s are based on CORBA IOR +definitions. + +<P> +All protocol-specific <TT>Profile</TT> implementations should inherit from the +<TT>TAO_Profile</TT> abstract base class. The <TT>TAO_Profile</TT> interface +is declared in the file +<TT><<A HREF="../../tao/Profile.h">tao/Profile.h></A></TT>. +Its interface follows. Only the methods that must be implemented are shown: + + +<P> + +<DL COMPACT> +<DT> +<DD>class TAO_Export TAO_Profile +<BR> +{ +<BR> + // = TITLE +<BR> + // Defines the Profile interface +<BR> + // +<BR> + // = DESCRIPTION +<BR> + // An abstract base class for representing object address or location +<BR> + // information. This is based on the CORBA IOR definitions. +<BR> + // +<BR> +public: +<BR> + +<BR> + virtual int parse_string (const char *string, +<BR> + CORBA::Environment &ACE_TRY_ENV) = 0; +<BR> + // Initialize this object using the given input string. +<BR> + // Supports URL style of object references +<BR> + +<BR> + virtual char* to_string (CORBA::Environment &ACE_TRY_ENV) = 0; +<BR> + // Return a string representation for this profile. client must +<BR> + // deallocate memory. +<BR> + +<BR> + virtual int decode (TAO_InputCDR& cdr) = 0; +<BR> + // Initialize this object using the given CDR octet string. +<BR> + +<BR> + virtual int encode (TAO_OutputCDR &stream) const = 0; +<BR> + // Encode this profile in a stream, i.e. marshal it. +<BR> + +<BR> + virtual TAO_ObjectKey *_key (void) const = 0; +<BR> + // Obtain the object key, return 0 if the profile cannot be parsed. +<BR> + // The memory is owned by the caller! +<BR> + +<BR> + virtual CORBA::Boolean is_equivalent (const TAO_Profile* other_profile) = 0; +<BR> + // Return true if this profile is equivalent to other_profile. Two +<BR> + // profiles are equivalent iff their key, port, host, object_key and +<BR> + // version are the same. +<BR> + +<BR> + virtual CORBA::ULong hash (CORBA::ULong max, +<BR> + CORBA::Environment &ACE_TRY_ENV) = 0; +<BR> + // Return a hash value for this object. +<BR> + +<BR> + virtual int addr_to_string (char *buffer, size_t length) = 0; +<BR> + // Return a string representation for the address. Returns +<BR> + // -1 if buffer is too small. The purpose of this method is to +<BR> + // provide a general interface to the underlying address object's +<BR> + // addr_to_string method. This allowsthe protocol implementor to +<BR> + // select the appropriate string format. +<BR> + +<BR> + virtual void reset_hint (void) = 0; +<BR> + // This method is used with a connection has been reset requiring +<BR> + // the hint to be cleaned up and reset to NULL. +<BR> +};</DD> +</DL>TAO's existing pluggable protocols have a static member containing the object +key delimiter specific to the given pluggable protocol, in addition to a static +protocol prefix accessor method that simply returns a pointer to a static string +containing the protocol prefix specific to the pluggable protocol. Note that +both of these members will always remain constant so there is no problem in +making them static. + +<P> +Theses static member are: + +<P> + +<DL> +<DT><STRONG><TT>object_key_delimiter</TT>.</STRONG></DT> +<DD>This <I>variable</I> contains the object key +delimiter specific to the given pluggable protocol. A typical definition looks +like: +<P> + +<DL COMPACT> +<DT> +<DD>const char TAO_IIOP_Profile::object_key_delimiter = '/';</DD> +</DL></DD> +<DT><STRONG><TT>prefix</TT>.</STRONG></DT> +<DD>This <I>method</I> simply returns a pointer to a static string +that contains the protocol prefix specific to the pluggable protocol in use. +The static string for the IIOP pluggable protocol is: + +<P> + +<DL COMPACT> +<DT> +<DD>static const char prefix_[] = "iiop";</DD> +</DL> +<P> +The IIOP <TT>prefix</TT> method is: + +<P> + +<DL COMPACT> +<DT> +<DD>const char * +<BR> +TAO_IIOP_Profile::prefix (void) +<BR> +{ +<BR> + return ::prefix_; +<BR> +}</DD> +</DL></DD> +</DL> +Note that it not strictly necessary to implement equivalent versions of these +static members. TAO's implementation just happens to use them. However, pluggable +protocol implementations that are based on TAO's pluggable protocols may need +them. + +<P> +Common to all concrete <TT>Profile</TT> implementations are a set of methods +that must be implemented. A description of each of these methods: + +<P> + +<DL> +<DT><STRONG>The Constructors.</STRONG></DT> +<DD>TAO's existing pluggable protocols each implement several +constructors in their concrete <TT>Profile</TT> classes. While pluggable protocols +are not strictly required to implement analogs to all of the constructors in +existing TAO pluggable protocols, it is generally a good idea to do so. All +of the constructors should initialize the <TT>TAO_Profile</TT> abstract base +class with the tag associated with the pluggable protocol. The object key should +also be set during <TT>Profile</TT> construction.</DD> +<P> +<DT><STRONG><TT>parse_string</TT>.</STRONG></DT> +<DD><TT>parse_string</TT> initialize a <TT>Profile</TT> +object using the provided string. The string passed to this method has the format: +<P> + +<DL COMPACT> +<DT> +<DD>N.n@address/object_key</DD> +</DL> +<P> +or + +<P> + +<DL COMPACT> +<DT> +<DD>address/object_key</DD> +</DL> +<P>where the <TT>address</TT> and the object key delimiter `<TT>/</TT>' are pluggable +protocol specific. The <TT>parse_string</TT> method must be able to extract +the protocol version (even if it isn't used), the address and the object key +from the provided string. It is generally a good idea to use the <TT>parse_string</TT> +methods in TAO's existing pluggable protocols as a reference when implementing +this method. + +<P> + </DD> +<DT><STRONG><TT>to_string</TT>.</STRONG></DT> +<DD>This method returns the URL style representation of the +object reference encapsulated by the <TT>Profile</TT> object. Most of this code +is also ``boilerplate.'' However, the address part of the URL style IOR, returned +by this method should be specific to the pluggable protocol. For example, the +address in the following IIOP URL style IOR: + +<P> + +<DL COMPACT> +<DT> +<DD>corbaloc:iiop:1.1@foo.bar.com:1234/yet_another_object_key</DD> +</DL> +<P>is ``<TT>foo.bar.com:1234</TT>.'' Much of the in TAO's existing pluggable +protocols may also be factored out because that code is common to all pluggable +protocols. The URL style IOR created by this method should be usable +by TAO's <A HREF="../INS.html">Interoperable Naming Service</A> via the +<TT><A HREF="../Options.html#-ORBInitRef">-ORBInitRef</A></TT> ORB option. + +<P> + </DD> +<DT><STRONG><TT>decode</TT>.</STRONG></DT> +<DD>The input CDR stream reference passed to this method is used +to initialize the <TT>Profile</TT> object, by extracting (<I>decoding</I> all +object reference information found within the CDR stream. Care must be taken +to extract the information in the correct order. Use existing TAO pluggable +protocol <TT>decode</TT> implementations as a reference. + +<P> +The <TT>decode</TT> method performs the inverse operation of the <TT>encode</TT> +method. + +<P> + </DD> +<DT><STRONG><TT>encode</TT>.</STRONG></DT> +<DD>This method inserts (<I>encodes</I> all of the information +encapsulated by the <TT>Profile</TT> object in to the provided output CDR stream. +Care must be taken to insert the information in the correct order. Use existing +TAO pluggable protocol <TT>encode</TT> implementations as a reference. + +<P> +The <TT>encode</TT> method performs the inverse operation of the <TT>decode</TT> +method. + +<P> + </DD> +<DT><STRONG><TT>_key</TT>.</STRONG></DT> +<DD>The <TT>_key</TT> method constructs a <TT>TAO_ObjectKey</TT> +object that is a <I>copy</I> of the object key found within the <TT>Profile</TT> +object, and returns a pointer to the newly create <TT>TAO_ObjectKey</TT> object. +Note that the <I>caller</I> owns the memory allocated by this method. TAO's +IIOP <TT>_key</TT> implementation is: + +<P> + +<DL COMPACT> +<DT> +<DD>ACE_INLINE TAO_ObjectKey * +<BR> +TAO_IIOP_Profile::_key (void) const +<BR> +{ +<BR> + TAO_ObjectKey *key = 0; +<BR> + +<BR> + ACE_NEW_RETURN (key, +<BR> + TAO_ObjectKey (this->object_key_), +<BR> + 0); +<BR> + +<BR> + return key; +<BR> +}</DD> +</DL></DD> +<P> +<DT><STRONG><TT>is_equivalent</TT>.</STRONG></DT> +<DD>The <TT>is_equivalent</TT> method implements the +CORBA specified method of the same name. It should return true if this profile +is equivalent to the profile to which it is being compared. Two profiles are +equivalent <I>if and only if</I> their tag, version, address and object key +are the same.</DD> +<P> +<DT><STRONG><TT>hash</TT>.</STRONG></DT> +<DD>The <TT>hash</TT> method implements the CORBA specified method +of the same name. It is expected to return 32 bit <TT>unsigned integer</TT> +(<TT>CORBA::ULong</TT>) that uniquely identifies the CORBA object referenced +by the <TT>Profile</TT> object. This method accepts an argument that specifies +the largest value the hash can be. + +<P> +Any algorithm deemed suitable to provide the required functionality may be used. +The <TT>ACE</TT> class in the ACE library provides implementations of several +hash algorithms. + +<P> + </DD> +<DT><STRONG><TT>addr_to_string</TT>.</STRONG></DT> +<DD><TT>addr_to_string</TT> returns a string representation +of the address. It should return <TT>-1</TT> if the supplied buffer is too small. +The stringified address should have the same form that the address in the URL +style IOR has. This method should be reentrant.</DD> +<P> +<DT><STRONG><TT>reset_hint</TT>.</STRONG></DT> +<DD>The <TT>reset_hint</TT> method resets the pointer to +a successfully used <TT>Connection Handler</TT>. If no pointer to such a <TT>Connection +Handler</TT>, i.e. a <I>hint</I> is provided by the pluggable protocol then this +method may be implemented as a ``no-op.'' A pluggable protcol that does not +provide a cached <TT>Connection Handler</TT> will not be able to take advantage +of improved <TT>Connector</TT> table look up times.</DD> +</DL> + +<P> + +<H3><A NAME="SECTION240" HREF="#TOC_SECTION240"> +The <TT>Protocol_Factory</TT> Object</A> +</H3> + +<P> +TAO's uses the ACE's Service Configurator implementation [<A + HREF="#Schmidt:94k">3</A>] +to dynamically load pluggable protocol factories. A <TT>Protocol_Factory</TT> +is responsible for creating the <TT>Acceptor</TT> and <TT>Connector</TT> for +the given pluggable protocol. TAO iterates through the list of loaded <TT>Protocol +Factories</TT> and invokes a factory operation that creates the desired object: +an <TT>Acceptor</TT> on the server-side, and a <TT>Connector</TT> on the client-side. + +<P> +All <TT>Protocol_Factory</TT> implementations should be derived from the <TT>TAO_Protocol_Factory</TT> +abstract base class defined in +<TT><<A HREF="../../tao/Protocol_Factory.h">tao/Protocol_Factory.h</A>></TT>. +The <TT>TAO_Protocol_Factory</TT> interface is shown below: + +<P> + +<DL COMPACT> +<DT> +<DD>class TAO_Export TAO_Protocol_Factory : public ACE_Service_Object +<BR> +{ +<BR> +public: +<BR> + TAO_Protocol_Factory (void); +<BR> + virtual ~TAO_Protocol_Factory (void); +<BR> + +<BR> + virtual int init (int argc, char *argv[]); +<BR> + // Initialization hook. +<BR> + +<BR> + virtual int match_prefix (const ACE_CString &prefix); +<BR> + // Verify prefix is a match +<BR> + +<BR> + virtual const char *prefix (void) const; +<BR> + // Returns the prefix used by the protocol. +<BR> + +<BR> + virtual char options_delimiter (void) const; +<BR> + // Return the character used to mark where an endpoint ends and +<BR> + // where its options begin. +<BR> + +<BR> + // Factory methods +<BR> + virtual TAO_Acceptor *make_acceptor (void); +<BR> + // Create an acceptor +<BR> + +<BR> + virtual TAO_Connector *make_connector (void); +<BR> + // Create a connector +<BR> + +<BR> + virtual int requires_explicit_endpoint (void) const = 0; +<BR> + // Some protocols should not create a default endpoint unless the +<BR> + // user specifies a -ORBEndpoint option. For example, local IPC +<BR> + // (aka UNIX domain sockets) is unable to remove the rendesvouz +<BR> + // point if the server crashes. For those protocols is better to +<BR> + // create the endpoint only if the user requests one. +<BR> +};</DD> +</DL>Each of the important methods to be implemented are described below: + +<P> + +<DL> +<DT><STRONG><TT>init</TT>.</STRONG></DT> +<DD>The <TT>init</TT> method is invoked immediately after the pluggable +protocol factory is loaded. The <TT>Service Configurator</TT> passes <TT>Protocol +Factory</TT> options specified in a <TT>Service Configurator</TT> configuration +file (e.g. <TT>svc.conf</TT>) to this method. The passing convention is essentially +the same as command line <TT>argc</TT>/<TT>argv</TT> argument passing convention. +The only difference lies in the fact that the option parsing should begin at +<TT>argv[0]</TT> instead of <TT>argv[1]</TT>. This differs from the +standard command line passing convention where <TT>argv[0]</TT> is the +name of the program currently being run. In any case, the <TT>init</TT> method +allows protocol-specific options to be implemented. Once passed to this method, +the pluggable protocol can use them to, for example, enable or disable certain +features or flags within the <TT>Protocol Factory</TT>. Other pluggable protocol +components can then use these flags or features as necessary. +<P> +A typical <TT>Service Configurator</TT> file line that loads a pluggable protocol +dynamically, and passes arguments to the <TT>init</TT> method would look like: + +<P> + +<DL COMPACT> +<DT> +<DD>dynamic IIOP_Factory Service_Object * TAO:_make_TAO_IIOP_Protocol_Factory() "-Foo Bar"</DD> +</DL> +<P> +In the above example, the arguments ``<TT>-Foo</TT>'' and ``<TT>Bar</TT>'' +would be passed as <TT>argv[0]</TT> and <TT>argv[1]</TT>, respectively, +to the <TT>Protocol_Factory init</TT> method. + +<P> + </DD> +<DT><STRONG><TT>match_prefix</TT>.</STRONG></DT> +<DD>This method verifies that protocol prefix contained +in the string passed to matches the one used by the pluggable protocol. A typical +implementation, such as the one used by the IIOP pluggable protocol, looks like: + +<P> + +<DL COMPACT> +<DT> +<DD>static const char prefix_[] = "iiop"; +<BR> + +<BR> +int +<BR> +TAO_IIOP_Protocol_Factory::match_prefix (const ACE_CString &prefix) +<BR> +{ +<BR> + // Check for the proper prefix for this protocol. +<BR> + return (ACE_OS::strcasecmp (prefix.c_str (), ::prefix_) == 0); +<BR> +}</DD> +</DL></DD> +<P> +<DT><STRONG><TT>prefix</TT>.</STRONG></DT> +<DD>The <TT>prefix</TT> method simply returns a pointer to the +static string containing the protocol prefix used by the pluggable protocol.</DD> +<P> +<DT><STRONG><TT>options_delimiter</TT>.</STRONG></DT> +<DD>The <TT>options_delimiter</TT> method is similar +to the <TT>object_key_delimiter</TT> method found in the <TT>Connector</TT>. +However, it used to delimit where an endpoint ends and where its options begin. +For example, the following <TT>-ORBEndpoint</TT> option specifies a endpoint-specific +priority: + +<P> + +<DL COMPACT> +<DT> +<DD>-ORBEndpoint iiop://1.1@foo.bar.com/priority=25</DD> +</DL> +<P> +To get around ambiguities in endpoints that can have a `<TT>/</TT>' character +in them, the <TT>options_delimiter</TT> method can be used to determine what +character to be used. For example, TAO's UIOP pluggable protocol implementation +defines the following: + +<P> + +<DL COMPACT> +<DT> +<DD>char +<BR> +TAO_UIOP_Protocol_Factory::options_delimiter (void) const +<BR> +{ +<BR> + return '|'; +<BR> +}</DD> +</DL> +<P> +An endpoint option for the UIOP pluggable protocol can look like the following: + +<P> + +<DL COMPACT> +<DT> +<DD>-ORBEndpoint uiop://1.1@/tmp/foo|priority=25</DD> +</DL> +<P> +Notice that the `<TT>|</TT>' character is used to mark where the rendezvous +point ends and where the endpoint-specific options begin. + +<P> + +<TT>options_delimiter</TT> is a server-side related method. It is of no use +to the client-side. + +<P> + </DD> +<DT><STRONG><TT>make_acceptor</TT>.</STRONG></DT> +<DD>The <TT>make_acceptor</TT> method is a factory method +that returns a pointer to a dynamically allocated <TT>Acceptor</TT> specific +to the pluggable protocol to which the <TT>Protocol_Factory</TT> object belongs. +TAO's UIOP pluggable protocol implementation defines this method as follows: + +<P> + +<DL COMPACT> +<DT> +<DD>TAO_Acceptor * +<BR> +TAO_UIOP_Protocol_Factory::make_acceptor (void) +<BR> +{ +<BR> + TAO_Acceptor *acceptor = 0; +<BR> + +<BR> + ACE_NEW_RETURN (acceptor, +<BR> + TAO_UIOP_Acceptor, +<BR> + 0); +<BR> + +<BR> + return acceptor; +<BR> +}</DD> +</DL></DD> +<P> +<DT><STRONG><TT>make_connector</TT>.</STRONG></DT> +<DD>The <TT>make_connector</TT> method is a factory +method that returns a pointer to a dynamically allocated <TT>Connector</TT> +specific to the pluggable protocol to which the <TT>Protocol_Factory</TT> object +belongs. TAO's UIOP pluggable protocol implementation defines this method as +follows: + +<P> + +<DL COMPACT> +<DT> +<DD>TAO_Connector * +<BR> +TAO_UIOP_Protocol_Factory::make_connector (void) +<BR> +{ +<BR> + TAO_Connector *connector = 0; +<BR> + +<BR> + ACE_NEW_RETURN (connector, +<BR> + TAO_UIOP_Connector, +<BR> + 0); +<BR> + +<BR> + return connector; +<BR> +}</DD> +</DL></DD> +<P> +<DT><STRONG><TT>requires_explicit_endpoint</TT>.</STRONG></DT> +<DD>Some protocols should not create a default +endpoint unless the user specifies a <TT>-ORBEndpoint</TT> option. For example, local +IPC (aka UNIX domain sockets) is unable to remove the rendesvouz point if the +server crashes. For those protocols, it is better to create the endpoint only +if the user requests one. This method is queried by TAO before creating a default +acceptor during ORB initialization. If it returns <TT>1</TT> then no default +endpoint should be created.</DD> +</DL> +<TT>Service Object</TT>s, such as the <TT>Protocol_Factory</TT>, must be declared +in a certain way. ACE's Service Configurator implementation provides two macros +to ensure that the required additional declarations are made to make an object +have to the correct interface. The two macros are <TT>ACE_STATIC_SVC_DECLARE</TT> +and <TT>ACE_FACTORY_DECLARE</TT>. Typical usage of these declaration macros +is demonstrated by TAO's UIOP pluggable protocol implementation: + +<P> + +<DL COMPACT> +<DT> +<DD>ACE_STATIC_SVC_DECLARE (TAO_UIOP_Protocol_Factory) +<BR> +ACE_FACTORY_DECLARE (TAO, TAO_UIOP_Protocol_Factory)</DD> +</DL>also required. These are provided by ``<TT>DEFINE</TT>'' counterparts of the +above two declaration macros. An example of how to use them follows: + +<P> + +<DL COMPACT> +<DT> +<DD>ACE_STATIC_SVC_DEFINE (TAO_UIOP_Protocol_Factory, +<BR> + ASYS_TEXT ("UIOP_Factory"), +<BR> + ACE_SVC_OBJ_T, +<BR> + &ACE_SVC_NAME (TAO_UIOP_Protocol_Factory), +<BR> + ACE_Service_Type::DELETE_THIS | +<BR> + ACE_Service_Type::DELETE_OBJ, +<BR> + 0) +<BR> + +<BR> +ACE_FACTORY_DEFINE (TAO, TAO_UIOP_Protocol_Factory)</DD> +</DL>Notice that the macro arguments above have corresponding <TT>Service Configurator</TT> +configuration file entries: + +<P> + +<DL COMPACT> +<DT> +<DD>dynamic UIOP_Factory Service_Object * TAO:_make_TAO_UIOP_Protocol_Factory() "" +<BR> +static Resource_Factory "-ORBProtocolFactory UIOP_Factory"</DD> +</DL> +<P> + +<H3><A NAME="SECTION250" HREF="#TOC_SECTION250"> +The <TT>Transport</TT> Object</A> +</H3> + +<P> + +<H3><A NAME="SECTION251" HREF="#TOC_SECTION251"> +Context</A> +</H3> + +<P> +It is desirable to provide for alternative mappings between different ORB messaging +protocols and ORB transport adaptors. For example, a single ORB messaging protocol +such as GIOP can be mapped to any reliable, connection-oriented transport protocol, +such as TCP or TP4. Alternatively, a single transport protocol can be the basis +for alternative instantiations of ORB messaging protocols, <I>e.g.</I>, different +versions of GIOP differing in the number and types of messages, as well as in +the format of those messages. + +<P> +An ORB messaging protocol imposes requirements on any underlying network transport +protocols. For instance, the transport requirements assumed by GIOP, see Section <A HREF="#IOP"><IMG ALIGN="BOTTOM" BORDER="1" ALT="[*]" + SRC="cross_ref_motif.png"></A>, +require the underlying network transport protocol to support a reliable, connection-oriented +byte-stream. These requirements are fulfilled by TCP thus leading to the direct +mapping of GIOP onto this transport protocol. However, alternative network transport +protocols such as ATM with AAL5 encapsulation may be more appropriate in some +environments. In this case, the messaging implementation will have to provide +the missing semantics, such as reliability, in order to use GIOP. + +<P> + +<H3><A NAME="SECTION252" HREF="#TOC_SECTION252"> +Problem</A> +</H3> + +<P> +The ORB Messaging protocol implementations must be independent of the adaptation +layer needed for transports that do not satisfy all their requirements. Otherwise, +the same messaging protocol may be re-implemented needlessly for each transport, +which is time-consuming, error-prone, and time/space inefficient. Likewise, +for those transports that can support multiple ORB Messaging protocols, it must +be possible to isolate them from the details of the ORB messaging implementation. +Care must be taken, however, because not all ORB Messaging protocols can be +used with all transport protocols, <I>i.e.</I>, some mechanism is needed to +ensure only semantically compatible protocols are configured [<A + HREF="#Johnson:95a">4</A>]. + +<P></P> +<DIV ALIGN="CENTER"><A NAME="iop_client"></A><A NAME="700"></A> +<TABLE> +<CAPTION ALIGN="BOTTOM"><STRONG>Figure 4:</STRONG> +Client Inter-ORB and Transport Class Diagram</CAPTION> +<TR><TD><P> + +<P> + +<DIV ALIGN="CENTER"> +<!-- MATH + $\resizebox* {5in}{!}{\includegraphics{graphics/pp_iopc.eps}}$ + --> +<IMG + WIDTH="568" HEIGHT="537" ALIGN="BOTTOM" BORDER="0" + SRC="img4.png" + ALT="pp_iopc"> </DIV> +<P> +<DIV ALIGN="CENTER"></DIV></TD></TR> +</TABLE> +</DIV><P></P> + +<P> + +<H3><A NAME="SECTION253" HREF="#TOC_SECTION253"> +Solution</A> +</H3> + +<P> +Use the Layers architecture pattern [<A + HREF="#Buschmann:95b">5</A>], which decomposes +the system into groups of components, each one at a different level of abstraction.<A NAME="tex2html5" + HREF="#foot549"><SUP>1</SUP></A> For the client, the ORB uses a particular ORB messaging protocol to send a +request. This ORB messaging protocol delegates part of the work to the transport +adapter component that completes the message and sends it to the server. If +the low-level transport in use, <I>e.g.</I>, ATM, UDP, TCP/IP, etc., does not +satisfy the requirements of the ORB messaging protocol, the ORB transport adapter +component can implement them. + +<P> +In the server, the transport adapter component receives data from the underlying +communication infrastructure, such as sockets or shared memory, and it passes +the message up to the ORB messaging layer. As with the client, this layer can +be very lightweight if the requirements imposed by the ORB messaging layer are +satisfied by the underlying network transport protocol. Otherwise, it must implement +those missing requirements by building them into the concrete transport adapter +component. + +<P></P> +<DIV ALIGN="CENTER"><A NAME="iop_server"></A><A NAME="702"></A> +<TABLE> +<CAPTION ALIGN="BOTTOM"><STRONG>Figure 5:</STRONG> +Server Inter-ORB and Transport Class Diagram</CAPTION> +<TR><TD><P> + +<P> + +<DIV ALIGN="CENTER"> +<!-- MATH + $\resizebox* {5in}{!}{\includegraphics{graphics/pp_iops.eps}}$ + --> +<IMG + WIDTH="422" HEIGHT="563" ALIGN="BOTTOM" BORDER="0" + SRC="img5.png" + ALT="pp_iops"> </DIV> +<P> +<DIV ALIGN="CENTER"></DIV></TD></TR> +</TABLE> +</DIV><P></P> + +<P> + +<H3><A NAME="SECTION254" HREF="#TOC_SECTION254"> +Applying the solution in TAO</A> +</H3> + + <P> + As shown in Figure <A HREF="#iop_client">4</A>, TAO + implements the messaging protocol and the transport protocol in + separate components. The client ORB uses the current profile to + find the right transport and ORB messaging implementations. The + creation and initialization of these classes is controlled by + the <A HREF="#design:connect"><TT>Connector</TT></A>, with each + <TT>Connector</TT> instance handling a particular ORB + messaging/transport tuple. + + + <P> + Figure <A HREF="#iop_server">5</A> illustrates how the + server's implementation uses the same transport classes, but + with a different relationship. In particular, the transport + class calls back the messaging class when data is received from + the IPC mechanism. As with the client, a factory, in this case + the <A HREF="#design:accept"><TT>Acceptor</TT></A>, creates and + initializes these objects. + +<P> + +<H3><A NAME="SECTION255" HREF="#TOC_SECTION255"> +<TT>Transport</TT> Implementation</A> +</H3> + +<P> +A <TT>Transport</TT> implements +external polymorphism [<A HREF="#Schmidt:97e">2</A>] over the +<TT>Client_Connection_Handler</TT> and the +<TT>Service_Connection_Handler</TT> objects described in the +<A HREF="#SECTION260"><TT>Connection_Handler</TT></A> section of this +document. A <TT>Connection_Handler</TT> is simply a template +instantiation of <TT>ACE_Svc_Handler<></TT>, but they don't do +much work. They just delegate on the <TT>Transport</TT> classes. +This somewhat strange design is easy to understand once it is realized +that not all <TT>ACE_Svc_Handler<></TT> classes are type +compatible (except in their most basic <TT>ACE_Event_Handler</TT> +form) so they must be wrapped using the <TT>TAO_Transport</TT> +class. + +<P> +All TAO pluggable protocol <TT>Transport</TT> classes must inherit from the +<TT>TAO_Transport</TT> abstract base class defined in <TT><<A HREF="../../tao/Transport.h">tao/Transport.h</A>></TT>. +The <TT>TAO_Transport</TT> interface is shown below. Again, only the methods +that should be implemented for a given pluggable protocol are shown: + +<P> + +<DL COMPACT> +<DT> +<DD>class TAO_Export TAO_Transport +<BR> +{ +<BR> + // = TITLE +<BR> + // Generic definitions for the Transport class. +<BR> + // +<BR> + // = DESCRIPTION +<BR> + // The transport object is created in the Service handler +<BR> + // constructor and deleted in the service handler's destructor!! +<BR> + +<BR> +public: +<BR> + TAO_Transport (CORBA::ULong tag, +<BR> + TAO_ORB_Core *orb_core); +<BR> + // default creator, requres the tag value be supplied. +<BR> + +<BR> + virtual ~TAO_Transport (void); +<BR> + // destructor +<BR> + +<BR> + virtual void close_connection (void) = 0; +<BR> + // Call the corresponding connection handler's <close> +<BR> + // method. +<BR> + +<BR> + virtual int idle (void) = 0; +<BR> + // Idles the corresponding connection handler. +<BR> + +<BR> + virtual ACE_HANDLE handle (void) = 0; +<BR> + // This method provides a way to gain access to the underlying file +<BR> + // handle used by the reactor. +<BR> + +<BR> + virtual ACE_Event_Handler *event_handler (void) = 0; +<BR> + // This method provides a way to gain access to the underlying event +<BR> + // handler used by the reactor. +<BR> + +<BR> + virtual ssize_t send (TAO_Stub *stub, +<BR> + const ACE_Message_Block *mblk, +<BR> + const ACE_Time_Value *s = 0) = 0; +<BR> + virtual ssize_t send (const ACE_Message_Block *mblk, +<BR> + const ACE_Time_Value *s = 0) = 0; +<BR> + // Write the complete Message_Block chain to the connection. +<BR> + // @@ The ACE_Time_Value *s is just a place holder for now. It is +<BR> + // not clear this this is the best place to specify this. The actual +<BR> + // timeout values will be kept in the Policies. +<BR> + +<BR> + virtual ssize_t send (const u_char *buf, +<BR> + size_t len, +<BR> + const ACE_Time_Value *s = 0) = 0; +<BR> + // Write the contents of the buffer of length len to the connection. +<BR> + +<BR> + virtual ssize_t recv (char *buf, +<BR> + size_t len, +<BR> + const ACE_Time_Value *s = 0) = 0; +<BR> + // Read len bytes from into buf. +<BR> + // @@ The ACE_Time_Value *s is just a place holder for now. It is +<BR> + // not clear this this is the best place to specify this. The actual +<BR> + // timeout values will be kept in the Policies. +<BR> + +<BR> + virtual void start_request (TAO_ORB_Core *orb_core, +<BR> + const TAO_Profile *profile, +<BR> + TAO_OutputCDR &output, +<BR> + CORBA::Environment &ACE_TRY_ENV = +<BR> + TAO_default_environment ()) +<BR> + ACE_THROW_SPEC ((CORBA::SystemException)); +<BR> + // Fill into <output> the right headers to make a request. +<BR> + +<BR> + virtual void start_locate (TAO_ORB_Core *orb_core, +<BR> + const TAO_Profile *profile, +<BR> + CORBA::ULong request_id, +<BR> + TAO_OutputCDR &output, +<BR> + CORBA::Environment &ACE_TRY_ENV = +<BR> + TAO_default_environment ()) +<BR> + ACE_THROW_SPEC ((CORBA::SystemException)); +<BR> + // Fill into <output> the right headers to make a locate request. +<BR> + +<BR> + virtual int send_request (TAO_Stub *stub, +<BR> + TAO_ORB_Core *orb_core, +<BR> + TAO_OutputCDR &stream, +<BR> + int twoway, +<BR> + ACE_Time_Value *max_time_wait) = 0; +<BR> + // Depending on the concurrency strategy used by the transport it +<BR> + // may be required to setup state to receive a reply before the +<BR> + // request is sent. +<BR> + // Using this method, instead of send(), allows the transport (and +<BR> + // wait strategy) to take appropiate action. +<BR> + +<BR> + virtual int handle_client_input (int block = 0, +<BR> + ACE_Time_Value *max_wait_time = 0); +<BR> + // Read and handle the reply. Returns 0 when there is Short Read on +<BR> + // the connection. Returns 1 when the full reply is read and +<BR> + // handled. Returns -1 on errors. +<BR> + // If <block> is 1, then reply is read in a blocking manner. +<BR> + +<BR> + virtual int register_handler (void); +<BR> + // Register the handler with the reactor. Will be called by the Wait +<BR> + // Strategy if Reactor is used for that strategy. Default +<BR> + // implementation out here returns -1 setting <errno> to ENOTSUP. +<BR> + +<BR> +};</DD> +</DL>Each method is described below: + +<P> + +<DL> +<DT><STRONG>The Constructor.</STRONG></DT> +<DD>As with all of the TAO pluggable protocol framework components +described so far, the constructor for the concrete <TT>Transport</TT> object +should also initialize the <TT>TAO_Transport</TT> base class with the tag corresponding +to the pluggable protocol.</DD> +<P> +<DT><STRONG><TT>close_connection</TT>.</STRONG></DT> +<DD>The underlying <TT>Connection Handler</TT>'s <TT>close</TT> +method is invoked my this method.</DD> +<P> +<DT><STRONG><TT>idle</TT>.</STRONG></DT> +<DD>This method idles the underlying <TT>Connection Handler</TT>.</DD> +<P> +<DT><STRONG><TT>handle</TT>.</STRONG></DT> +<DD>This method returns the underlying file handle used by the +<TT>Reactor</TT>.</DD> +<P> +<DT><STRONG><TT>event_handler</TT>.</STRONG></DT> +<DD>This method returns the underlying <TT>Event Handler</TT> +used by the <TT>Reactor</TT>.</DD> +<P> +<DT><STRONG><TT>send</TT>.</STRONG></DT> +<DD>The <TT>send</TT> writes data to the connection established +in the underlying transport, such as a TCP connection in the IIOP pluggable +protocol. Three versions of this method must be implemented. Two of them write +data contained within an <TT>ACE_Message_Block</TT> and the remaining simply +sends the data within a buffer of a given length. +<P> +When implementing this method, it is important to be aware of the correct underlying +<TT>send</TT> or <TT>write</TT> operation to use. Some of TAO's existing pluggable +protocols use the <TT>send</TT> calls provided by the operating system because +no further processing of the data being sent is necessary. However, other protocols +may process perform additional operations on the data being sent, in which case +the <TT>send</TT> operation provided by the underlying protocol implementation +should be used instead of the raw operating system <TT>send</TT> call. +</DD> +<P> +<DT><STRONG><TT>recv</TT>.</STRONG></DT> +<DD>The <TT>recv</TT> operation reads a given number of bytes into +a supplied buffer. Unlike the <TT>send</TT> method, there is only one version +of the <TT>recv</TT> operation. The same caveat of ensuring that the appropriate +<TT>recv</TT> or <TT>read</TT> operation is used also applies to this method.</DD> +<P> +<DT><STRONG><TT>start_request</TT>.</STRONG></DT> +<DD>This method creates the appropriate header to make +a request and write it into the provided output CDR stream. This method is closely +tied to TAO's GIOP implementation. <TT>start_request</TT> implementations should +essentially be the same in all pluggable protocol implementations. The only +thing that should differ is the type of <TT>Profile</TT> being used. Note that +this method is only useful for clients.</DD> +<P> +<DT><STRONG><TT>start_locate</TT>.</STRONG></DT> +<DD>This method creates the appropriate header to make +a <I>locate</I> request and write it into the provided output CDR stream. This +method is closely tied to TAO's GIOP implementation. <TT>start_locate</TT> +implementations should essentially be the same in all pluggable protocol implementations. +The only thing that should differ is the type of <TT>Profile</TT> being used. +Note that this method is only useful for clients. Note that this method is only +useful for clients.</DD> +<P> +<DT><STRONG><TT>send_request</TT>.</STRONG></DT> +<DD>Depending on the concurrency strategy used by the transport +it may be required to setup state to receive a reply before the request is sent. +Using this method, instead of <TT>send</TT>, allows the transport (and wait +strategy) to take appropiate action. This method is closely tied to TAO's GIOP +implementation. <TT>send_request</TT> implementations should essentially be +the same in all pluggable protocol implementations. The only thing that should +differ is the type of <TT>Profile</TT> being used. Note that this method is +only useful for clients.</DD> +<P> +<DT><STRONG><TT>handle_client_input</TT>.</STRONG></DT> +<DD><TT>handle_client_input</TT> reads and handles +the reply from the server. It returns zero when there is <TT>Short Read</TT> +on the connection, returns <TT>1</TT> when the full reply is read and handled, +and returns <TT>-1</TT> on errors. Note that this method is only useful for +clients.</DD> +<P> +<DT><STRONG><TT>register_handler</TT>.</STRONG></DT> +<DD>This method registers the <TT>Connection Handler</TT> +with the <TT>Reactor</TT>. It will be called by the <TT>Wait Strategy</TT> if +the <TT>Reactor</TT> is used for that strategy. This code should essentially +be ``boilerplate'' code. It shouldn't differ much between pluggable protocol +implementations if the same ACE event handling and dispatching components are +used. Note that this method may be deprecated in the future.</DD> +</DL> +There other methods in the <TT>TAO_Transport</TT> that can be overridden. However, +the default implementations should be more than satisfactory for most pluggable +protocols. + +<P> +TAO's existing pluggable protocols implement client-side and server-side specific +<TT>Transport</TT>s. For the most part, they can be used as references for other +pluggable protocols. + +<H3><A NAME="SECTION260" HREF="#TOC_SECTION260"> +The <TT>Connection_Handler</TT></A> +</H3> +A <TT>Connection_Handler</TT> is simply a template instantiation of +<TT>ACE_Svc_Handler<></TT> [<A HREF="#Schmidt:97c">1</A>], +a service handler. <TT>ACE_Svc_Handler</TT>s provide a well-defined +interface that <TT>Acceptor</TT> and <TT>Connector</TT> pattern +factories use as their target. Service handlers perform +application-specific processing and communicate via the connection +established by the <TT>Connector</TT> and <TT>Acceptor</TT> +components. Typically, TAO <TT>Connection_Handler</TT>s will subclass +<TT>ACE_Svc_Handler</TT> and do all the interesting work in the +subclass. + +<P> + +<H3><A NAME="SECTION261" HREF="#TOC_SECTION261"> +<TT>Connection_Handler</TT> Implementation</A> +</H3> + +TAO pluggable transport protocol <TT>Connection_Handler</TT>s should +be derived from the <TT>ACE_Svc_Handler</TT> class declared in +<<A + HREF="../../../ace/Svc_Handler.h"><TT>ace/Svc_Handler.h</TT></A>>. TAO's existing pluggable transport protocol +implementations define three classes, a base class derived from an +<TT>ACE_Svc_Handler</TT> specific to that protocol, and a client-side +and a server-side class derived from that base class. Generally, it +is a good idea to base new <TT>Connection_Handler</TT> implementations +on TAO's existing ones. The interfaces for the existing +<TT>Connection_Handler</TT>s are defined in +<<A HREF="../../tao/IIOP_Connect.h"><TT>tao/IIOP_Connect.h</TT></A>> +and +<<A HREF="../../tao/UIOP_Connect.h"><TT>tao/UIOP_Connect.h</TT></A>>. + +<P> +<HR> +<P> + +<H3><A NAME="SECTION300" HREF="#TOC_SECTION300"> +Notes From a ``Real World'' Pluggable Protocol Implementation</A> +</H3> + +By Bruce Trask <<A +HREF="mailto:btrask@contactsystems.com">btrask@contactsystems.com</A>> + +<P>This section is based on notes I took when adding a different +transport layer to the TAO ORB. I was given some initial guidelines +on adding an additional protocol and these proved very helpful. +Beyond that there was not much more documentation and so I hope the +information in this paper will serve to further assist anybody whose +is adding a pluggable protocol to the TAO ORB. + +<P>I found that in order to successfully add the new protocol capabilities, one had to +have a very good understanding of some of the patterns upon which the ACE framework +is built. These are the REACTOR, ACCEPTOR, CONNECTOR, FACTORY, STRATEGY, +and SERVICE CONFIGURATOR PATTERN. The papers that I found helpful on these +were: +<BR> +<BLOCKQUOTE> +Reactor ( +<A HREF="http://www.cs.wustl.edu/~schmidt/Reactor.ps.gz">PostScript</A> | +<A HREF="http://www.cs.wustl.edu/~schmidt/PDF/Reactor.pdf">PDF</A> +)<BR> + +Reactor1-93 ( +<A HREF="http://www.cs.wustl.edu/~schmidt/Reactor1-93.ps.gz">PostScript</A> | +<A HREF="http://www.cs.wustl.edu/~schmidt/PDF/Reactor1-93.pdf">PDF</A> +)<BR> + +Reactor2-93 ( +<A HREF="http://www.cs.wustl.edu/~schmidt/Reactor2-93.ps.gz">PostScript</A> | +<A HREF="http://www.cs.wustl.edu/~schmidt/PDF/Reactor2-93.pdf">PDF</A> +)<BR> + +reactor-rules ( +<A HREF="http://www.cs.wustl.edu/~schmidt/reactor-rules.ps.gz">PostScript</A> | +<A HREF="http://www.cs.wustl.edu/~schmidt/PDF/reactor-rules.pdf">PDF</A> +)<BR> + +reactor-siemens ( +<A HREF="http://www.cs.wustl.edu/~schmidt/reactor-siemens.ps.gz">PostScript</A> | +<A HREF="http://www.cs.wustl.edu/~schmidt/PDF/reactor-siemens.pdf">PDF</A> +)<BR> + +Svc-Conf ( +<A +HREF="http://www.cs.wustl.edu/~schmidt/Svc-Conf.ps.gz">PostScript</A> | +<A HREF="http://www.cs.wustl.edu/~schmidt/PDF/Svc-Conf.pdf">PDF</A> +)<BR> + +Acc-Con ( +<A HREF="http://www.cs.wustl.edu/~schmidt/Acc-Con.ps.gz">PostScript</A> +<A HREF="http://www.cs.wustl.edu/~schmidt/PDF/Acc-Con.pdf">PDF</A> +) +</BLOCKQUOTE> +<P>These are all readily available from the TAO and ACE website. +<P>My starting point for understanding how to add a pluggable protocol +to the TAO ORB came from mailing list entry from <A +HREF="mailto:coryan@uci.edu">Carlos O'Ryan</A>. One can find it +in the archives of the comp.soft-sys.ace newsgroup. It is dated +1999/06/02 RE: [ace-users] TAO: ATM pluggable protocol. I will repeat +the section of that email that was particularly useful to me. (In the +email, he is responding to someone who had inquired about adding the +ATM protocol). <p> + +<BLOCKQUOTE> +Basically, you need to look at the following files:<BR> + +<BLOCKQUOTE> +IIOP_Profile.{h,i,cpp}<BR> +IIOP_Connector.{h,i,cpp}<BR> +IIOP_Acceptor.{h,i,cpp}<BR> +IIOP_Factory.{h,i,cpp}<BR> +IIOP_Transport.{h,i,cpp}<BR> +Connect.{h,i,cpp} [probably will be renamed IIOP_Connect VSN] +</BLOCKQUOTE> + +<P> +The profile class handles the addressing format for your transport. +It would basically be a wrapper around the ACE_ATM_Addr() class. The +Connector and Acceptor classes are simply wrappers around +ACE_Acceptor<ACE_ATM_ACCEPTOR> and +ACE_Connector<ACE_ATM_ACCEPTOR>, again no big deal (I think). +The factory is even simpler. + +<P> +Things get really interesting in the Transport and Connect classes. +Transport just implements external polymorphism over the +Client_Connection_Handler and the Service_Connection_Handler objects +defined in the Connect.{h,i,cpp}, those are simply +ACE_Svc_Handler<ACE_ATM_Stream>, but they don't do much work, +they just delegate on the Transport classes. This somewhat strange +design is easy to understand once you realize that all the +ACE_Svc_Handler<> classes are not type compatible (except in +their most basic ACE_Event_Handler form). So they must be wrapped +using the TAO_Transport class. +</BLOCKQUOTE> + + +<P>Make sure to review +``<A HREF="../releasenotes/index.html#pp">Pluggable Protocols</A>'' +in +``<A HREF="../releasenotes/index.html">Release Information for the ACE +ORB (TAO)</A>'' +in the +<A HREF="../releasenotes">TAO/docs/releasenotes</A> directory. +<BR><P> +Just for completeness sake, I'll include some other mailing list entries which were helpful +in getting me started. The following is from <A HREF="mailto:ossama@uci.edu">Ossama Othman</A>. + +<BLOCKQUOTE>The stock TAO distribution has support for two transport protocols, +TCP/IP and local namespace sockets (aka Unix Domain sockets). However, +TAO's pluggable protocols framework allows users to add support for +additional transport protocols. All you'd really have to do is +implement a SCRAMNet pluggable transport protocol with the interface +TAO's pluggable protocol framework provides and you'd be able to use +SCRAMNet with TAO just as easily as the IIOP (GIOP over TCP/IP) and +UIOP (GIOP over Unix domains sockets) protocols. +<P> +The idea is to implement GIOP messaging over a SCRAMNet transport. If +you model your implementation on TAO's IIOP and UIOP implementations +then it should be fairly straightforward to create a SCRAMNet +pluggable protocol for TAO. The hard part is implementing the +equivalent ACE classes for SCRAMNet. +<P> +. . . +<P> +It's actually not that bad. The easiest way to add a pluggable protocol +to TAO, IMO, is to base your pluggable protocol on existing ones. As +long as you have the same interface for your protocol as the existing +ones then it is fairly easy to create your TAO pluggable protocol. +However, in order to do that you have to create ACE_SCRAMNet_{Acceptor, +Connector, Stream, Addr} implementations, for example, since TAO's +existing pluggable protocols use those interfaces. + +<P> +As long as you use the same interface for your protocol as the +interface for ace/ACE_SOCK* and tao/IIOP* then you shouldn't have much +of a problem. +</BLOCKQUOTE> + +<P> +This also assumes that you're implementation can satisfy the +conditions stated earlier in this document. + +<P>Note also that the TAO files pluggable.* +are important to review and understand as they contain the abstract +classes that form the common inteface for TAO's pluggable protocol +framework. <BR> <P>Getting a full understanding on how IIOP was +implemented (GIOP over TCP/IP) and also seeing how provisions were +made to add UIOP, was very helpful to adding my own protocol. In +understanding IIOP, I needed to review the section of the OMG CORBA +spec on GIOP, IIOP and Object references and see how this would apply +to my protocol. <BR> + +<P>In my case, I added a transport layer that uses SCRAMNet (from +Systran Corp) replicated shared memory hardware. This is actual +physical memory cards located on two different machines. When a +change is made to one memory then that change appears very quickly +(very low latency here) in the other memory. I decided that I would +implement GIOP over SCRAMNet as this seemed to be the simplest. With +SCRAMNet, one could implement this transport layer for the TAO ORB in +a few different ways, GIOP over SCRAMNet, Environment-specific +inter-ORB protocol (ESIOP) or using collocation (since it is shared +replicated memory). I have not done the latter two, only GIOP over +SCRAMNet just to get a proof of concept working. + +<BR><P> For a graphical representation of the extensions for the new +SCRAMNet classes I have may a skeletal Rose diagram showing (at this +point) the inheritance relationships of the new and existing classes. +See (TBD) ftp site for this Rose diagram. + +<BR><P> +The new classes created were. +<BR> +<BLOCKQUOTE> +TAO_SCRAMNet_Profile (Derived from TAO_Profile in <A HREF="../../tao/Profile.h">Profile.h</A>)<BR> +TAO_SCRAMNet_Acceptor (Derived from TAO_Acceptor in <A HREF="../../tao/Pluggable.h">Pluggable.h</A>) <BR> +TAO_SCRAMNet_Connector (Derived from TAO_Connector in <A HREF="../../tao/Pluggable.h">Pluggable.h</A>)<BR> +TAO_SCRAMNet_Transport (Derived from TAO_Transport in <A HREF="../../tao/Pluggable.h">Pluggable.h</A>) + <BLOCKQUOTE>TAO_SCRAMNet_Server_Transport<BR> + TAO_SCRAMNet_Client_Transport</BLOCKQUOTE> +TAO_SCRAMNet_Protocol_Factory (Derived from TAO_Protocol Factory in <A HREF="../../tao/Protocol_Factory.h">Protocol_Factory.h</A>)<BR> +TAO_SCRAMNet_Handler_Base (as in <A HREF="../../tao/IIOP_Connect.h">IIOP_Connect.h</A>) + <BLOCKQUOTE>TAO_SCRAMNet_Client_Connection_Handler<BR> + TAO_SCRAMNet_Server_Connection_Handler</BLOCKQUOTE></BLOCKQUOTE> +<BLOCKQUOTE>ACE_SCRAMNet_Addr<BR> +ACE_SCRAMNet_Acceptor<BR> +ACE_SCRAMNet_Connector<BR> +ACE_SCRAMNet_Stream</BLOCKQUOTE> +<P>I closely followed the way that IIOP and UIOP were defined and implemented in the definition and +implementation of the SCRAMNet classes. Following the existing protocol implementation was +the largest source of help for me. Being able to step through the operation of the ORB for +the IIOP protocol and then transposing that over to my protocol made the process relatively painless +and quite the learning experience. +<BR><P> + +I am using TAO under Phar Lap's Embedded Tool Suite Real-Time +Operating System which is an RTOS which supports a subset of the Win32 +API and Winsock 1.1. Because of the new SCRAMNet transport hardware I +needed to change the ORBs core reactor to a WFMO_Reactor. Any +instance of the TAO ORB can only have one reactor type or it won't +work. In my case I am using an ORB in one thread that uses the +WFMO_Reactor and the SCRAMNet transport, and an ORB in another thread +that uses a Select Reactor and the IIOP protocol. I won't go into +much of the SCRAMNet specific stuff as I assume most people are +interested in adding a pluggable protocol in general. <BR><P> + +<P> + +RE: IORs<BR> +I found that I needed to have a full understanding of what the exact contents of +a TAO-created IOR were as I needed to be able to understand how to decode the +location information that was now written in the IOR with the SCRAMNet +specific information. Decoding of the preconnect and endpoint info is important. +The endpoint info both in the command line arguments and in the IOR are different +for the each protocol and so your implemention of the new classes has to parse this +information correctly. +<BR><P> +In order to create the ORB with the Win32 Reactor at the core as well as the +SCRAMNet protocol factory loaded and initialize I needed to use the +svc.conf file with the the following options +<A HREF="../Options.html#-ORBReactorType">-ORBReactorType</A> wfmo +<A HREF="../Options.html#-ORBProtocolFactory">-ORBProtocolFactory</A> SCRAMNet_Factory +<BR><P> + +</OL> + +Beyond the above, I just traced through the operation of the IIOP +protocol in action to see exactly where I needed to just graft on the +new ACE_SCRAMNet classes, the TAO_SCRAMNet classes and their +associated implementations for send and recv so that the SCRAMNet +hardware was used as the transport and not the ethernet hardware. +Questions, comments, changes are welcome. I can be reached at <A +HREF="mailto:btrask@contactsystems.com">btrask@contactsystems.com</A> + +<P> +<HR> +<P> + +<H3> +<A NAME="SECTION400" HREF="#TOC_SECTION400"> +Additional Implementation Information +</A> +</H3> + +<P> +This section covers additional information not necessarily related to +TAO's pluggable protocol framework but may still be of interest to +pluggable protocol and ORB developers, nevertheless. + +<H3> +<A NAME="SECTION410" HREF="#TOC_SECTION410"> +Tags +</A> +</H3> + +Tags are used to uniquely identify certain parts of an ORB, including +the following: +<P> +<UL> +<LI>vendor</LI> +<LI>profile</LI> +<LI>service</LI> +<LI>component</LI> +<LI>ORB type</LI> +</UL> +<P> +A list of current <A HREF="http://www.omg.org/">OMG</A> assigned tags +is available at: +<BLOCKQUOTE> +<A HREF="ftp://ftp.omg.org/pub/docs/ptc/99-05-02.txt">ftp://ftp.omg.org/pub/docs/ptc/99-05-02.txt</A> +</BLOCKQUOTE> +<P> +For information about tags and tag allocation see: +<BLOCKQUOTE> +<A HREF="http://www.omg.org/cgi-bin/doc?ptc/99-02-01">http://www.omg.org/cgi-bin/doc?ptc/99-02-01</A> +</BLOCKQUOTE> + +<P> +Information about tags used in TAO is available +<A HREF="../Tags.html">here</A>. + +<P> +<HR> +<P> + +<H3><A NAME="SECTION500" HREF="#TOC_SECTION500"> +Using a Pluggable Protocol</A> +</H3> + +<P> +Once a TAO pluggable protocol is implemented, the ORB is told to load it by +adding entries to a <TT>Service Configurator</TT> configuration file (e.g. <TT>svc.conf</TT> +for that protocol. A typical <TT>svc.conf</TT> file could contain entries such +as the following: + +<P> + +<DL COMPACT> +<DT> +<DD> +dynamic FOOIOP_Factory Service_Object * TAO_FOO:_make_TAO_FOOIOP_Protocol_Factory() "" +<BR> +static Resource_Factory "-ORBProtocolFactory FOOIOP_Factory" +<P> +</DD> +</DL>These entries would cause a pluggable protocol called ``FOOIOP'' to be loaded +into the ORB. By default the IIOP and UIOP (if supported) pluggable protocols +are loaded into TAO if no such entries are provided. Explicitly specifying which +protocols to load in this way prevents any pluggable protocols from being loaded +by default. The +<TT><A HREF="../Options.html#-ORBProtocolFactory">-ORBProtocolFactory</A></TT> +ORB option causes the specified protocol factory to be loaded into the +ORB. + +Multiple pluggable protocols can be loaded simply by adding more +<TT>Service Configurator</TT> configuration file entries. For example, the following +entries would cause the TAO's IIOP and the fictional FOOIOP pluggable protocols +to be loaded: + +<P> + +<DL COMPACT> +<DT> +<DD>dynamic FOOIOP_Factory Service_Object * TAO_FOO:_make_TAO_FOOIOP_Protocol_Factory() "" +<BR> +static Resource_Factory "-ORBProtocolFactory FOOIOP_Factory" +<BR> +dynamic IIOP_Factory Service_Object * TAO:_make_TAO_IIOP_Protocol_Factory() "" +<BR> +static Resource_Factory "-ORBProtocolFactory IIOP_Factory" +<P> +</DD> +</DL>In this case, TAO's UIOP pluggable protocol would <I>not</I> be +loaded. <TT>Service Configurator</TT> configuration file names are +not limited to the name ``<TT>svc.conf</TT>.'' The ORB can be told +to use a configuration file other than ``<TT>svc.conf</TT>'' by using the +<TT><A HREF="../Options.html#-ORBSvcConf">-ORBSvcConf</A></TT> +ORB option. + + +<P> +Note that the FOOIOP protocol resides in a library other than the TAO +library, called ``<TT>libTAO_FOO.so</TT>'' on UNIX platforms, and +``<TT>TAO_FOO.dll</TT>'' on Win32 platforms. This ability to +dynamically load pluggable protocols in libraries that are completely +separate libraries from the TAO library truly makes TAO's pluggable +protocol framework ``pluggable.'' Make sure the directory your +pluggable protocol library is located in is also in your library +search path, typically <TT>LD_LIBRARY_PATH</TT> on UNIX systems and/or +the ``<TT>/etc/ld.so.conf</TT>'' file on some UNIX systems. Remember +to run <TT>ldconfig</TT> if you modify ``<TT>/etc/ld.so.conf</TT>.'' + +<P> +Creating an endpoint specific to a given pluggable protocol is simply a matter +of using TAO's <TT><A HREF="../Options.html#-ORBEndpoint">-ORBEndpoint</A></TT> ORB option. This is detailed in the documentation +for the +<TT><A HREF="#TAO_Acceptor::open">open</A></TT> +and +<TT><A HREF="#TAO_Acceptor::open_default">open_default</A></TT> +methods in the +<TT><A HREF="#SECTION210">Acceptor</A></TT> +section of this document. Once an endpoint is created, the client uses +the IOR that points to the object on that endpoint to make requests on +that object. + +<P> +All ORB options are described <A HREF="../Options.html">here</A>. + +<P> +<HR> +<P> + +<H3><A NAME="SECTION600" HREF="#TOC_SECTION600"> +Bibliography</A> +</H3><DL COMPACT><DD><P></P><DT><A NAME="Schmidt:97c">1</A> +<DD> +D. C. Schmidt, +``<A HREF=http://www.cs.wustl.edu/~schmidt/PDF/Acc-Con.pdf> + Acceptor and Connector: Design Patterns for Initializing + Communication Services</A>,'' + in <EM> Pattern Languages of Program Design</EM> + (R. Martin, F. Buschmann, and D. Riehle, eds.), Reading, MA: Addison-Wesley, + 1997. + +<P></P><DT><A NAME="Schmidt:97e">2</A> +<DD> +C. Cleeland, D. C. Schmidt and T. Harrison, +``<A HREF=http://www.cs.wustl.edu/~schmidt/PDF/External-Polymorphism.pdf> + External Polymorphism -- An Object Structural Pattern for + Transparently Extending Concrete Data Types</A>,'' + in <EM> Pattern Languages of Program Design</EM> + (R. Martin, F. Buschmann, and D. Riehle, eds.), Reading, MA: Addison-Wesley, + 1997. + +<P></P><DT><A NAME="Schmidt:94k">3</A> +<DD> +D. C. Schmidt and T. Suda, + ``<A HREF=http://www.cs.wustl.edu/~schmidt/PDF/DSEJ-94.pdf> + An Object-Oriented Framework for Dynamically + Configuring Extensible Distributed Communication Systems</A>,'' <EM> IEE/BCS + Distributed Systems Engineering Journal (Special Issue on Configurable + Distributed Systems)</EM>, vol. 2, pp. 280-293, December 1994. + +<P></P><DT><A NAME="Johnson:95a">4</A> +<DD> +H. Hueni, R. Johnson, and R. Engel, ``A Framework for Network Protocol + Software,'' in <EM> Proceedings of OOPSLA '95</EM>, (Austin, Texas), ACM, + October 1995. + +<P></P><DT><A NAME="Buschmann:95b">5</A> +<DD> +F. Buschmann, R. Meunier, H. Rohnert, P. Sommerlad, and M. Stal, <A +HREF="http://www.cs.wustl.edu/~schmidt/POSA/">Pattern-Oriented Software +Architecture - A System of Patterns</EM>.</A> Wiley and Sons, 1996. + +<P></P><DT><A NAME="Schmidt:99x">6</A> +<DD> +Carlos O'Ryan, Fred Kuhns, Douglas C. Schmidt, Ossama Othman, and Jeff +Parsons, <A +HREF="http://www.cs.wustl.edu/~schmidt/PDF/pluggable_protocols.pdf"> The +Design and Performance of a Pluggable Protocols Framework for +Real-time Distributed Object Computing Middleware</A>, Proceedings of +the IFIP/ACM <A +HREF="http://www.research.ibm.com/Middleware2000/">Middleware 2000</A> +Conference, Pallisades, New York, April 3-7, 2000. <P> + +<P></P><DT><A NAME="Schmidt:99c">7</A> <DD> Fred Kuhns, Carlos O'Ryan, +Douglas C. Schmidt, Ossama Othman, and Jeff Parsons, <A +HREF="http://www.cs.wustl.edu/~schmidt/PDF/PfHSN.pdf">The Design and +Performance of a Pluggable Protocols Framework for Object Request +Broker Middleware,</A> Proceedings of the <A +HREF="http://www.isi.edu/pfhsn99/call.html">IFIP Sixth International +Workshop on Protocols For High-Speed Networks (PfHSN '99)</A>, Salem, +MA, August 25--27, 1999. <P> + +</DL> + +<P> + +<HR><H4>Footnotes</H4> +<DL> +<DT><A NAME="foot549">... abstraction.</A><A NAME="foot549" + HREF="#tex2html5"><SUP>1</SUP></A> +<DD>Protocol stacks based on the Internet or ISO OSI reference models are common +examples of the Layers architecture. + + +</DL><HR> + <ADDRESS><a href="mailto:ossama@uci.edu">Ossama Othman</a></ADDRESS> +<!-- Created: Tue Dec 14 16:53:58 CST 1999 --> +<!-- hhmts start --> +Last modified: Sat Dec 8 10:43:59 PST 2001 +<!-- hhmts end --> +</BODY> +</HTML> diff --git a/TAO/docs/pluggable_protocols/pluggable_protocols.css b/TAO/docs/pluggable_protocols/pluggable_protocols.css new file mode 100644 index 00000000000..1993b851311 --- /dev/null +++ b/TAO/docs/pluggable_protocols/pluggable_protocols.css @@ -0,0 +1,31 @@ + +/* Century Schoolbook font is very similar to Computer Modern Math: cmmi */ +.MATH { font-family: "Century Schoolbook", serif; } +.MATH I { font-family: "Century Schoolbook", serif; font-shape: italic } +.BOLDMATH { font-family: "Century Schoolbook", serif; font-weight: bold } + +/* implement both fixed-size and relative sizes */ +SMALL.XTINY { font-size : xx-small } +SMALL.TINY { font-size : x-small } +SMALL.SCRIPTSIZE { font-size : smaller } +SMALL.FOOTNOTESIZE { font-size : small } +SMALL.SMALL { } +BIG.LARGE { } +BIG.XLARGE { font-size : large } +BIG.XXLARGE { font-size : x-large } +BIG.HUGE { font-size : larger } +BIG.XHUGE { font-size : xx-large } + +/* heading styles */ +H1 { } +H2 { } +H3 { } +H4 { } +H5 { } + +/* mathematics styles */ +DIV.displaymath { } /* math displays */ +TD.eqno { } /* equation-number cells */ + + +/* document-specific styles come next */ |