The TAO's interceptor implementation has been revised so that it conforms to the Portable Interceptor specification which is now a part of the CORBA 2.6.1 specification. The purpose of this document is to provide a transition guide for those who have used our old interceptors. The old interceptors will no longer be supported now that we have the new mechanism in place. A paper that describes TAO's portable interceptors and smart proxies is available online.
Interceptors allow you to interpose other CORBA services to the ORB and extend the ORB's functionalities. They are most commonly used in, but not limited to, Security Service, Transaction Service. They are also for accounting, auditing and debugging distributed applications.
The TAO's interceptor interface has been modified to conform with the CORBA
2.5 spec. The current implementation of interceptors consists of support
for the Dynamic
module as well as the canonical interception
points including (1) send_request
, (2)
receive_reply
, (3) receive_exception
, (4)
receive_other
, (5)
receive_request_service_contexts
, (6)
receive_request
, (7) send_reply
, (8)
send_exception
, (9) send_other
, and (10)
establish_components
(specific to
IORInterceptor
s). Each request interception point is passed
a RequestInfo
object which encapsulates the details of the
operation like arguments, etc. The IOR interception point is passed an
IORInfo
object that encapsulates operations for adding
tagged components to profiles in an IOR. Registration of all three types
of interceptors (client and server request interceptors, and IOR
interceptors) is now done using the interface provided by the standard
ORBInitInfo
object.
Details of this implementation along with benchmarking is available in the paper on Meta-programming mechanisms.
Examples on this new version of Portable Interceptors is available at
$TAO_ROOT/tests/Portable_Interceptors
.
Please refer to CORBA 2.5 specification for details on the proposed Portable Interceptor interfaces. Below is the old but now obsolete interceptor version in TAO.
// -*- IDL -*- $Id: interceptors.html,v 1.1 2004/03/16 14:38:05 tao Exp $ // This file contains the interface definitions for "Portable" // Interceptor support. // ********************************************************** // Notice that the Portable Interceptor specification // is still under discussion in OMG and both the IDL // and the implementation details in TAO will eventually // change to conform with the PI spec in the future. // // @@ Now that a working draft of the Portable Interceptors // is available, we will provide a compliant implementation // shortly. // // Please see the annotation marked with "@@" in this file // for hints on transitting from the temporary // implementation to new APIs. // // See $TAO_ROOT/docs/interceptors.html for more info. // ********************************************************** // Author (currently): Nanbor Wang <NANBOR@CS.WUSTL.EDU> // @@ I will no longer be the author of this IDL file. #include <CORBA.PIDL> #include <IOP.PIDL> #pragma prefix "TAO" // The prefix should be changed to "omg.org" once the spec. gets // finallized. // @@ The prefix will be changed to "omg.org". module PortableInterceptor { interface Cookie { // Cookie's are used to pass information among interceptors // within a invocation or an upcall. // // @@ Cookie will no longer be available. string myname (); }; typedef sequence%gt;COOKIE%lt; Cookies; // Collections of Cookie's become Cookies'es. // // @@ Cookies will no longer be available. interface Interceptor { // Base interface for Interceptors. // // @@ This interface will not change. readonly attribute string name; }; interface ServerRequestInterceptor : Interceptor { // Server side request interceptor definition. // // @@ The name of the interface will not change. void preinvoke (in unsigned long request_id, in boolean response_expected, in CORBA::Object objref, in string operation_name, inout IOP::ServiceContextList sc, inout NVList arguments, inout Cookies ck); // Interception pointer before invoking the servant method. // Currently, we don't pass NVList into the interceptor because // I haven't figured out how to best optimize this stuff. // In the future, NVList will contain all in and inout arguments // of the operation. // // @@ This operation will map to either // <receive_request_service_contexts> or <receive_request> of // the standard APIs. If you are not sure, use // <receive_request>. // // void receive_request_service_contexts (in ServerRequestInfo ri) raises (ForwardRequest); // void receive_request (in ServerRequestInfo ri) raises (ForwardRequest); // // @@ Note that all arguments will be accessed thru // <PortableInterceptor::ServerRequestInfo> interface. void postinvoke (in unsigned long request_id, in boolean response_expected, in CORBA::Object objref, in string operation_name, inout IOP::ServiceContextList sc, inout NVList arguments, inout Cookies ck); // Interception pointer after invoking the servant method. // Currently, we don't pass NVList into the interceptor because // I haven't figured out how to best optimize this stuff. // In the future, NVList will contain all out, inout arguments // and the return value of the operation. // // @@ This operation will map to <send_reply>. // It is not clear whether oneway call will invoke <send_other> // operation or not. // // void send_reply (in ServerRequestInfo ri); // void send_other (in ServerRequestInfo ri) raises (ForwardRequest); // // @@ Note that all arguments will be accessed thru // <PortableInterceptor::ServerRequestInfo> interface. void exception_occurred (in unsigned long request_id, in boolean response_expected, in CORBA::Object objref, in string operation_name, inout Cookies ck); // Exception interception point. // // @@ This method will map to <send_exception> method. // // void send_exception (in ServerRequestInfo ri) raises (ForwardRequest); // // @@ Note that all arguments will be accessed thru // <PortableInterceptor::ServerRequestInfo> interface. }; interface ClientRequestInterceptor : Interceptor { // Client side interceptor. // // @@ The name of the interface will not change. void preinvoke (in unsigned long request_id, in boolean response_expected, in CORBA::Object objref, in string operation_name, inout IOP::ServiceContextList sc, inout NVList arguments, inout Cookies ck); // Before remote invocation. // Currently, we don't pass NVList into the interceptor because // I haven't figured out how to best optimize this stuff. // In the future, NVList will contain all in and inout arguments // of the operation. // // @@ This operation will map to <send_request> of the standard // APIs. // // void send_request (in ClientRequestInfo) raises (ForwardRequest); // // @@ Note that all arguments will be accessed thru // <PortableInterceptor::ClientRequestInfo> interface. void postinvoke (in unsigned long request_id, in boolean response_expected, in CORBA::Object objref, in string operation_name, inout IOP::ServiceContextList sc, inout NVList arguments, inout Cookies ck); // After returned from remote invocation. // Currently, we don't pass NVList into the interceptor because // I haven't figured out how to best optimize this stuff. // In the future, NVList will contain all out, inout arguments // and the return value of the operation. // // @@ This operation will map to either <receive_reply> or // <receive_other> in the standard APIs depending on whether the // operation is oneway or not. // // void receive_reply (in ClientRequestInfo ri); // void receive_other (in ClientRequestInfo ri); // // @@ Note that all arguments will be accessed thru // <PortableInterceptor::ClientRequestInfo> interface. void exception_occurred (in unsigned long request_id, in boolean response_expected, in CORBA::Object objref, in string operation_name, inout Cookies ck); // Exception occurred. // // @@ This method will map to <receive_exception> method as: // // void receive_exception (in ClientRequestInfo ri) raises (ForwardRequest); // // @@ Note that all arguments will be accessed thru // <PortableInterceptor::ClientRequestInfo> interface. }; }; #pragma prefix ""
send_request
,
receive_reply
, receive_exception
,
receive_other
,
receive_request_service_contexts
,
receive_request
, send_reply
,
send_exception
, send_other
, and
establish_components
. The remaining client request
interception point, send_poll
, is time independent
invocation specific. Once TAO supports time independent
invocations, the send_poll
interception point will be
implemented.ORBInitializer
registration has been implemented, as
per the spec.ORBInitInfo
class. Multiple interceptors may now be
registered.ORBInitInfo::register_policy_factory
, has been
implemented. Corresponding policies can then be created using the
ORB::create_policy
method.ORBInitInfo::register_initial_reference
, has been
implemented. This is particularly useful for registering local objects
with the ORB's resolve_initial_references
mechanism since
they can't be stringified and registered via -ORBInitRef
ORB option.ORBInitInfo
methods have been
implemented except allocate_slot_id
.ClientRequestInfo
,
ServerRequestInfo
and IORInfo
methods.PortableInterceptor::ForwardRequest
exception on both the
client and server sides.IOP::CodecFactory
and the CDR
encapsulation IOP::Codec
objects. The CDR encapsulation
Codec
is useful for embedding data in an
octet
sequence that conforms to the CDR encapsulation
rules. For example, it could be used to marshal data into the
octet
sequence that is part of an
IOP::ServiceContext
or an
IOP::TaggedComponent
. This means that it could compliment
the IOR interceptor support, and the service context manipulation
support found in request interceptors.PortableInterceptor::ServerRequestInfo::object_id
,
PortableInterceptor::ServerRequestInfo::adapter_id
and
PortableServer::POA::id
methods.PortableInterceptor::RequestInfo::arguments
method for
the case when a given target method has more than one parameter.Dynamic::Parameter
IDL. It now
correctly uses the CORBA::ParameterMode
enumeration in
place of the Dynamic::ParameterMode
enumeration. The
latter has been removed since it was not a standard type.PortableInterceptor::ClientRequestInterceptor::send_request
interception point now occurs before a connection attempt to the
target is ever made. This greatly improves the speed of client request
interceptor initiated LOCATION_FORWARD
s, in addition to
making it possible to prevent connection attempts from occuring by
throwing an exception, for example.PortableInterceptor::ForwardRequest
exception support. It is longer possible to throw a
PortableInterceptor::ForwardRequest
exception in
application code (i.e. not an interceptor) and expect it to be
converted to a LOCATION_FORWARD
. A
PortableInterceptor::ForwardRequest
exception will now
only be treated as a LOCATION_FORWARD
if it is thrown
from an interception point capable of raising that exception.
Otherwise it will be propagated to the client. This change also has
the added benefit of reducing the stub/skeleton footprint,
particularly for IDL with many interfaces.PortableInterceptor::Current
interface,
ORBInitInfo::allocate_slot_id
,
ClientRequestInfo::get_slot
,
ServerRequestInfo::get_slot
,
ServerRequestInfo::set_slot
, and
ServerRequestInfo::get_server_policy
methods.ThruPOA
collocation optimization
to the interceptor chain; the direct
collocation
optimization will not go through the interceptor chain.send_poll
request interception point
implementation will most likely be deferred until TII is supported in
TAO.direct
or ThruPOA
.ClientRequestInfo::{arguments,exceptions,result}() are not
available for AMI calls.