2 <TITLE>Portable Interceptors
</TITLE>
6 <H3>Portable Interceptors
</H3>
13 <p>We have revised TAO's interceptor implementation so that it
14 conforms to the Portable Interceptor specification which is now a part
15 of the
<a href=
"http://www.omg.org/cgi-bin/doc?formal/04-03-01">CORBA
16 3.0.3</A> specification. The purpose of this document is to provide a
17 transition guide for those who have used our old interceptors. The
18 old interceptors will no longer be supported now that we have the new
19 mechanism in place. A paper that describes TAO's portable
20 interceptors and
<A HREF=
"Smart_Proxies.html">smart proxies
</A> is
22 <A HREF=
"http://www.dre.vanderbilt.edu/~schmidt/PDF/smart_proxies.pdf">online
</A>.
26 <h3><a name=
"toc">Table of Contents
</a></h3>
28 <li><a href=
"#context">Context
</a>
29 <li><a href=
"#implement">TAO's Implementation
</a>
30 <li><a href=
"#api">Transition
</a>
31 <li><a href=
"#status">Current Status
</a>
32 <li><a href=
"#future">Future Work
</a>
33 <li><a href=
"#issues">Known Issues
</a>
34 <li><a href=
"#ref">References
</a>
38 <h2><a name=
"context">Context
</a></h2>
40 <p>Interceptors allow you to interpose other CORBA services to the ORB
41 and extend the ORB's functionalities. They are most commonly used in,
42 but not limited to, Security Service, Transaction Service. They are
43 also for accounting, auditing and debugging distributed applications.
47 <h3><a name=
"implement">TAO's Implementation of
"Portable
48 Interceptors"</a></h3>
50 <p>We have modifed TAO's interceptor interface to conform with the
51 CORBA
2.5 spec. The current implementation of interceptors consists of
52 support for the
<CODE>Dynamic
</CODE> module as well as the canonical
53 interception points including
54 (
1)
<CODE>send_request
</CODE>,
55 (
2)
<CODE>receive_reply
</CODE>,
56 (
3)
<CODE>receive_exception
</CODE>,
57 (
4)
<CODE>receive_other
</CODE>,
58 (
5)
<CODE>receive_request_service_contexts
</CODE>,
59 (
6)
<CODE>receive_request
</CODE>,
60 (
7)
<CODE>send_reply
</CODE>,
61 (
8)
<CODE>send_exception
</CODE>,
62 (
9)
<CODE>send_other
</CODE>, and
63 (
10)
<CODE>establish_components
</CODE> (specific to
64 <CODE>IORInterceptor
</CODE>s). Each request interception point is
65 passed a
<CODE>RequestInfo
</CODE> object which encapsulates the
66 details of the operation like arguments, etc. The IOR interception
67 point is passed an
<CODE>IORInfo
</CODE> object that encapsulates
68 operations for adding tagged components to profiles in an IOR.
69 Registration of all three types of interceptors (client and server
70 request interceptors, and IOR interceptors) is now done using the
71 interface provided by the standard
<CODE>ORBInitInfo
</CODE>
75 Details of this implementation along with benchmarking is available in
77 href=
"http://www.dre.vanderbilt.edu/~schmidt/PDF/COOTS-00.pdf">Meta-programming
81 <p> Examples on this new version of Portable Interceptors is available
82 at
<CODE>$TAO_ROOT/tests/Portable_Interceptors
</CODE>.
</p>
85 <h3><a name=
"api">Transitting from TAO's Old
"Portable"
86 Interceptor APIs to the Standard Portable Interceptor APIs
</a></h3>
88 <p>Please refer to CORBA
2.5 specification for details on the proposed
89 Portable Interceptor interfaces. Below is the old but now obsolete
90 interceptor version in TAO.
</p>
95 // This file contains the interface definitions for
"Portable"
96 // Interceptor support.
98 // **********************************************************
99 // Notice that the Portable Interceptor specification
100 // is still under discussion in OMG and both the IDL
101 // and the implementation details in TAO will eventually
102 // change to conform with the PI spec in the future.
104 // @@ Now that a working draft of the Portable Interceptors
105 // is available, we will provide a compliant implementation
108 // Please see the annotation marked with
"@@" in this file
109 // for hints on transitting from the temporary
110 // implementation to new APIs.
112 // See $TAO_ROOT/docs/interceptors.html for more info.
113 // **********************************************************
115 // Author (currently): Nanbor Wang
<nanbor@cs.wustl.edu
>
116 // @@ I will no longer be the author of this IDL file. ;-)
118 #include
<corba.pidl
>
122 // The prefix should be changed to
"omg.org" once the spec. gets
124 // @@ The prefix will be changed to
"omg.org".
126 module PortableInterceptor
130 // Cookie's are used to pass information among interceptors
131 // within a invocation or an upcall.
133 // @@ Cookie will no longer be available.
137 typedef sequence
<Cookie> Cookies;
138 // Collections of Cookie's become Cookies'es.
140 // @@ Cookies will no longer be available.
142 interface Interceptor
144 // Base interface for Interceptors.
146 // @@ This interface will not change.
147 readonly attribute string name;
150 interface ServerRequestInterceptor : Interceptor
152 // Server side request interceptor definition.
154 // @@ The name of the interface will not change.
156 void preinvoke (in unsigned long request_id,
157 in boolean response_expected,
158 in CORBA::Object objref,
159 in string operation_name,
160 inout IOP::ServiceContextList sc,
161 inout NVList arguments,
163 // Interception pointer before invoking the servant method.
164 // Currently, we don't pass NVList into the interceptor because
165 // I haven't figured out how to best optimize this stuff.
166 // In the future, NVList will contain all in and inout arguments
169 // @@ This operation will map to either
170 //
<receive_request_service_contexts
> or
<receive_request
> of
171 // the standard APIs. If you are not sure, use
172 //
<receive_request
>.
174 // void receive_request_service_contexts (in ServerRequestInfo ri) raises (ForwardRequest);
175 // void receive_request (in ServerRequestInfo ri) raises (ForwardRequest);
177 // @@ Note that all arguments will be accessed thru
178 //
<PortableInterceptor::ServerRequestInfo
> interface.
180 void postinvoke (in unsigned long request_id,
181 in boolean response_expected,
182 in CORBA::Object objref,
183 in string operation_name,
184 inout IOP::ServiceContextList sc,
185 inout NVList arguments,
187 // Interception pointer after invoking the servant method.
188 // Currently, we don't pass NVList into the interceptor because
189 // I haven't figured out how to best optimize this stuff.
190 // In the future, NVList will contain all out, inout arguments
191 // and the return value of the operation.
193 // @@ This operation will map to
<send_reply
>.
194 // It is not clear whether oneway call will invoke
<send_other
>
197 // void send_reply (in ServerRequestInfo ri);
198 // void send_other (in ServerRequestInfo ri) raises (ForwardRequest);
200 // @@ Note that all arguments will be accessed thru
201 //
<PortableInterceptor::ServerRequestInfo
> interface.
203 void exception_occurred (in unsigned long request_id,
204 in boolean response_expected,
205 in CORBA::Object objref,
206 in string operation_name,
208 // Exception interception point.
210 // @@ This method will map to
<send_exception
> method.
212 // void send_exception (in ServerRequestInfo ri) raises (ForwardRequest);
214 // @@ Note that all arguments will be accessed thru
215 //
<PortableInterceptor::ServerRequestInfo
> interface.
218 interface ClientRequestInterceptor : Interceptor
220 // Client side interceptor.
222 // @@ The name of the interface will not change.
224 void preinvoke (in unsigned long request_id,
225 in boolean response_expected,
226 in CORBA::Object objref,
227 in string operation_name,
228 inout IOP::ServiceContextList sc,
229 inout NVList arguments,
231 // Before remote invocation.
232 // Currently, we don't pass NVList into the interceptor because
233 // I haven't figured out how to best optimize this stuff.
234 // In the future, NVList will contain all in and inout arguments
237 // @@ This operation will map to
<send_request
> of the standard
240 // void send_request (in ClientRequestInfo) raises (ForwardRequest);
242 // @@ Note that all arguments will be accessed thru
243 //
<PortableInterceptor::ClientRequestInfo
> interface.
245 void postinvoke (in unsigned long request_id,
246 in boolean response_expected,
247 in CORBA::Object objref,
248 in string operation_name,
249 inout IOP::ServiceContextList sc,
250 inout NVList arguments,
252 // After returned from remote invocation.
253 // Currently, we don't pass NVList into the interceptor because
254 // I haven't figured out how to best optimize this stuff.
255 // In the future, NVList will contain all out, inout arguments
256 // and the return value of the operation.
258 // @@ This operation will map to either
<receive_reply
> or
259 //
<receive_other
> in the standard APIs depending on whether the
260 // operation is oneway or not.
262 // void receive_reply (in ClientRequestInfo ri);
263 // void receive_other (in ClientRequestInfo ri);
265 // @@ Note that all arguments will be accessed thru
266 //
<PortableInterceptor::ClientRequestInfo
> interface.
268 void exception_occurred (in unsigned long request_id,
269 in boolean response_expected,
270 in CORBA::Object objref,
271 in string operation_name,
273 // Exception occurred.
275 // @@ This method will map to
<receive_exception
> method as:
277 // void receive_exception (in ClientRequestInfo ri) raises (ForwardRequest);
279 // @@ Note that all arguments will be accessed thru
280 //
<PortableInterceptor::ClientRequestInfo
> interface.
288 <h3><a name=
"status">Current Status
</a></h3>
290 <li>The core infrastructure is in place as well as the canonical
291 request and IOR interception points:
292 <CODE>send_request
</CODE>,
293 <CODE>receive_reply
</CODE>,
294 <CODE>receive_exception
</CODE>,
295 <CODE>receive_other
</CODE>,
296 <CODE>receive_request_service_contexts
</CODE>,
297 <CODE>receive_request
</CODE>,
298 <CODE>send_reply
</CODE>,
299 <CODE>send_exception
</CODE>,
300 <CODE>send_other
</CODE>, and
301 <CODE>establish_components
</CODE>.
302 The remaining client request interception point,
303 <CODE>send_poll
</CODE>, is
<EM>time independent invocation
</EM>
304 specific. Once TAO supports time independent invocations, the
305 <CODE>send_poll
</CODE> interception point will be implemented.
306 <li><CODE>ORBInitializer
</CODE> registration has been implemented,
308 <li>Registration of interceptors is now conformant to the spec
309 through the
<CODE>ORBInitInfo
</CODE> class. Multiple
310 interceptors may now be registered.
311 <li>IOR interceptors have been implemented. They allow an external
312 service, for example, to add tagged components to profiles
313 within IORs as they are being generated.
314 <li>Policy factory registration, i.e.
315 <CODE>ORBInitInfo::register_policy_factory
</CODE>, has been
316 implemented. Corresponding policies can then be created using
317 the
<CODE>ORB::create_policy
</CODE> method.
318 <li>Initial reference registration, i.e.
319 <CODE>ORBInitInfo::register_initial_reference
</CODE>, has been
320 implemented. This is particularly useful for registering local
321 objects with the ORB's
<CODE>resolve_initial_references
</CODE>
322 mechanism since they can't be stringified and registered via
323 <CODE>-ORBInitRef
</CODE> ORB option.
324 <li>Basically, all
<CODE>ORBInitInfo
</CODE> methods have been
325 implemented except
<CODE>allocate_slot_id
</CODE>.
326 <li>Implemented most of the remaining
327 <CODE>ClientRequestInfo
</CODE>,
<CODE>ServerRequestInfo
</CODE>
328 and
<CODE>IORInfo
</CODE> methods.
329 <li>Added support for the
330 <CODE>PortableInterceptor::ForwardRequest
</CODE>
331 exception on both the client and server sides.
332 <li>Implemented the
<CODE>IOP::CodecFactory
</CODE> and the CDR
333 encapsulation
<CODE>IOP::Codec
</CODE> objects. The CDR
334 encapsulation
<CODE>Codec
</CODE> is useful for embedding data in
335 an
<CODE>octet
</CODE> sequence that conforms to the CDR
336 encapsulation rules. For example, it could be used to marshal
337 data into the
<CODE>octet
</CODE> sequence that is part of an
338 <CODE>IOP::ServiceContext
</CODE> or an
339 <CODE>IOP::TaggedComponent
</CODE>. This means that it could
340 compliment the IOR interceptor support, and the service context
341 manipulation support found in request interceptors.
343 <CODE>PortableInterceptor::ServerRequestInfo::object_id
</CODE>,
344 <CODE>PortableInterceptor::ServerRequestInfo::adapter_id
</CODE>
346 <CODE>PortableServer::POA::id
</CODE> methods.
347 <li>Greatly improved the speed of the
348 <CODE>PortableInterceptor::RequestInfo::arguments
</CODE> method
349 for the case when a given target method has more than one
351 <li>Corrected the
<CODE>Dynamic::Parameter
</CODE> IDL. It now
352 correctly uses the
<CODE>CORBA::ParameterMode
</CODE> enumeration
353 in place of the
<CODE>Dynamic::ParameterMode
</CODE>
354 enumeration. The latter has been removed since it was not a
357 <CODE>PortableInterceptor::ClientRequestInterceptor::send_request
</CODE>
358 interception point now occurs before a connection attempt to the
359 target is ever made. This greatly improves the speed of client
360 request interceptor initiated
<CODE>LOCATION_FORWARD
</CODE>s, in
361 addition to making it possible to prevent connection attempts
362 from occuring by throwing an exception, for example.
363 <li>Corrected
<CODE>PortableInterceptor::ForwardRequest
</CODE>
364 exception support. It is longer possible to throw a
365 <CODE>PortableInterceptor::ForwardRequest
</CODE> exception in
366 application code (i.e. not an interceptor) and expect it to be
367 converted to a
<CODE>LOCATION_FORWARD
</CODE>. A
368 <CODE>PortableInterceptor::ForwardRequest
</CODE> exception will
369 now only be treated as a
<CODE>LOCATION_FORWARD
</CODE> if it is
370 thrown from an interception point capable of raising that
371 exception. Otherwise it will be propagated to the client. This
372 change also has the added benefit of reducing the stub/skeleton
373 footprint, particularly for IDL with many interfaces.
374 <li>Implemented
<CODE>PortableInterceptor::Current
</CODE> interface,
375 <CODE>ORBInitInfo::allocate_slot_id
</CODE>,
376 <CODE>ClientRequestInfo::get_slot
</CODE>,
377 <CODE>ServerRequestInfo::get_slot
</CODE>,
378 <CODE>ServerRequestInfo::set_slot
</CODE>, and
379 <CODE>ServerRequestInfo::get_server_policy
</CODE> methods.
380 <li>Client interception points are now invoked for AMI calls.
384 <h2><a name=
"future">Future Work
</a></h2>
386 <li>Add support for the
<CODE>ThruPOA
</CODE> collocation
387 optimization to the interceptor chain; the
<CODE>direct
</CODE>
388 collocation optimization will not go through the interceptor
390 <li>The
<CODE>send_poll
</CODE> request interception point
391 implementation will most likely be deferred until TII is
396 <h3><a name=
"issues">Known Issues
</a></h3>
398 <li>Currently none.
</li>
402 <H3><a name=
"ref">References
</a></H3>
404 <LI><A HREF=
"http://www.omg.org/cgi-bin/doc?formal/04-03-01">formal/
2004-
03-
01</A> -- CORBA
3.0.3 Specification -- contains the Portable Interceptors chapter
</LI>