Issue 3321: Portable Interceptors: ORB mediated calls in ORB initializers
Issue 3432: ORB access needed in IDL for Interceptors
Issue 3435: Interceptors and finalization
Issue 3440: adapter_activator
Issue 3450: Getting rid of ORB PIDL
Issue 3523: PortableInterceptor::ForwardRequest vs PortableServer::ForwardRequest
Issue 3524: What if the target application code raises ForwardRequest?
Issue 3545: org.omg.PortableInterceptor.ORBInitializerClass.XXX on command line?
Issue 3568: Relax the restriction of 9.1.1
Issue 3586: Server-side thread-scoped PICurrent to request-scoped PICurrent problem
Issue 3598: Java mapping of register_orb_initializer
Issue 3611: Global-Scoped Invocations viz-a-viz ORB-scoped slot ids
Issue 3619: Thread context switches
Issue 3625: resolve_initial_references should be OK in ORBInitInfo::pre_init
Issue 3626: CORBA as a layer in layered systems
Issue 3628: resolve should be ok in pre_init
Issue 3640: target_is_a wrong?
Issue 3642: Affects of INS on Interceptors - resolve_initial_references
Issue 3653: Should get/set_slot on PICurrent be disallowed in ORBInitializer?
Issue 3660: IORInfo::get_effective_policy access to POA policies
Issue 3661: Two-phased IORInterceptor
Issue 3662: IORTemplate
Issue 3663: IORInterceptor invoked on each Object Adapter Creation
Issue 3664: Persistent Server Id
Issue 3666: Persistent Server Port
Issue 3667: Object Adapter Destroy Interceptor
Issue 3677: Interceptors must provide user-level request ID
Issue 3678: Interceptors must provide a retry mechanism
Issue 3679: PI must provide a means for security interceptors to clean up
Issue 3683: New issue: Server Side Flow Clarification
Issue 3684: It is not clear when ORB initializers are meant to be called
Issue 3693: PI: Bi-endianness of Codec Factory
Issue 3742: resolution order (resolution to issue 3642)
Issue 3766: Security needs access to servant and POA
Issue 3769: Example of ORBInitializer usage needed
Issue 3771: Portable Interceptors viz-a-viz LOCATION_FORWARD_PERMANENT
Issue 3777: Exact text for IORInfo::get_effective_policy
Issue 3790: exceptions in pre_init & post_init
Issue 3791: pre_init & post_init synchronization
Issue 3935: IOP_N
Issue 3981: table 4-1, page 63 has a mistake in its list for TRANSIENT minor codes
Issue 4139: GIOP 1.2 Fragmentation and Interceptors
Issue 4168: LocateRequest
Issue 4174: Do the client & server side interceptors see LocateRequest messages?
Issue 4291: Interceptors and the Java "Local Optimized" stubs
Issue 4494: ORBInitInfo.resolve_initial_references() should return Object
Issue 3321: Portable Interceptors: ORB mediated calls in ORB initializers (interceptors-rtf)
Click here for this issue's archive.
Source: IONA (Mr. Matthew Newhook, )
Nature: Uncategorized Issue
Severity:
Summary:
Are ORB mediated calls allowed in the ORB initializers? If so, are interceptors applied to these calls?
I would like us to seriously consider a different option - to change ORB >itself to be a local interface rather than a pseudo-object. If we were >starting from scratch, I see no reason that we wouldn't do it that way. >I'd like to know what the implications are of switching it to a local >interface now.
the current PI spec doesn't give interceptors any chance to finalize themselves. As far as interceptors are concerned, the process simply disappears. That's rather bad news. For example, interceptors may allocate memory, open files, or do similar things with other resources. If interceptors are not given a chance to finalize themselves, that means they cannot clean up those resources. Depending on the environment, that can be positively disastrous. For example, in many environments, disappearing without freeing memory first causes a permanent and hard memory leak because there is no operating system to clean up after a task or process. It appears that PI needs to add a finalization call and define when exactly that call runs for client- and server-side interceptors.
Should interceptors be called before POA adapter activators are called?
I think it would be worth discussing this at a slightly higher level. I have made the argument before that we're kidding ourselves by believing that we can convince people to throwout the existing PIDL infrastructure instantly. As engineers we KNOW that there are cleaner approaches, and that by using some of the newer features that we've added to IDL and by being a bit more clever we can probably produce a much better architecture.
We have two exceptions in CORBA that look almost identical: PortableInterceptor::ForwardRequest and PortableServer::ForwardRequest. We did not want the PortableInterceptor module to depend on PortableServer so we made our own version of the exception. This new version added "boolean permanent" to the exception which does not exist in the PortableServer version. But a thread of discussion now exists in interop@omg.org to determine whether LOCATION_FORWARD_PERM should be deprecated. If it IS deprecated, then the two versions of ForwardRequest will be identical. If that occurs, would it make sense to combine the two exceptions into one exception located outside of either module? Or should we just leave it as is?
Should the ORB care whether ForwardRequest is raised by an interceptor or by the target application code? If no, then the client code will look a bit odd: void proc () raises (PortableInterceptor::ForwardRequest); because the client will have to catch this exception even though this exception will never get to the client. If yes, then we must specifically restrict the meaning of ForwardRequest to something like: "this exception will only cause a location forward if raised by an interceptor."
In Java, we have defined a property for ORBInitializers. But we do not define how they can be set on the command line. Do we think it is necessary? If so, then... Does the Java mapping spec provide a mechanism for setting the defined parameters via the command line? The Core provides for command line arguments of the form "-ORBXXX". The Java mapping chapter does not map "-ORBXXX" to properties. I believe it's generally assumed that "-ORBXXX" is equivalent to a property with a name of "org.omg.CORBA.XXX". If this IS defined somewhere, I would appreciate someone pointing it out to me. Now back to my question. How do we get the equivalent of "org.omg.PortableInterceptor.ORBInitializerClass.XXX" passed on the command line? Can we simply do "-ORBInitializerClass.XXX"? That would be going somewhat contrary to convention of "-ORB" meaning "org.omg.CORBA", but we could do it.
Section 9 of orbos/99-12-02 describes the ORBInitInfo operations register_initial_reference and resolve_initial_reference, and places restrictions on when they can be used: 9.1.1 pre_init: "All calls to ORBInitInfo::register_initial_reference must be made at this point so that the list of initial references is complete for the post_init_point." 9.2.7 resolve_initial_references: "This operation is only valid during post_init." I assume that these restrictions are to remove ordering dependencies between interceptors - if A needs to use an initial service registered by B, then we can run the pre_inits for A and B in either order, and then the post_inits for A and B in either order. That's understandable, but I believe may be too restrictive in practice. For example, an interceptor may need to register an initial service but it will expect to find the object reference via a location service such as Naming or Trading -available as initial services "NameService" or "TradingService". I propose we relax the restriction of 9.1.1, and replace it by guidance such as: "If it is expected that initial services registered by an interceptor will be used by other interceptors, then those initial services should be registered at this point via calls to ORBInitInfo::register_initial_reference." Note that the same functionality will be available via the ORB after initialization anyway (11.1), so it seems a little arbitrary to forbid it only during the post_init phase.
In document ptc/00-03-03, page 21-35, point 5 states: 5. The ORB logically copies the RSC to the server-side TSC after the receive_request_service_context points are processed and before the servant manager is called. >>>>>This TSC is within the context for both the invocation of the servant manager and the invocation of the target operation.<<<<< The receive_request points may modify the RSC, but this no longer affects the TSC. I've bracketed the questionable sentence between >>>>> <<<<<. The problem arises in point 8: 8. The TSC is copied back to the RSC, overwriting the slots in the RSC. WHICH thread-scoped current is copied back to the request-scoped current? We have at least 2 threads to worry about - the servant manager thread and the target operation thread - and these could themselves spawn other threads. Which current is supposed to be copied back to the request? I suggest the following change to point 8: 8. The TSC from the thread on which the ORB invoked the target operation is copied back to the RSC, overwriting the slots in the RSC.
There appears to be some confusion in section 21.7.3.1 of ptc/2000-04-05 in the definition of the Java mapping for register_orb_initializer ... "The new property names are of the form: org.omg.PortableInterceptor.ORBInitializerClass.<Service> where <Service> is the string name of a class which implements org.omg.PortableInterceptor.ORBInitializer." specifies that a portion of the property name is used to identify the ORBInitializer class to instantiate; the semantics of the property value are left undefined. However the example: "To run a program called MyApp using this logging service, the user could type: java -Dorg.omg.PortableInterceptor.ORBInitializerClass.com.x.Log- ging = com.x.Logging.LoggingService MyApp" implies that its the property value that identfies this class, and that the property name (needlessly) specifies its package. Can anyone indicate which of the above are the correct semantics for org.omg.PortableInterceptor.ORBInitializerClass properties? Also this section seems to confuse ORB properties (which I would understand to be those set via the properties parameter to org.omg.CORBA.ORB.init()) with system properties (i.e. those set via java -Dname=value).
Invocations are global-scoped but slot ids are ORB-scoped. This does not work in the presence of multiple ORBS.
Through a rather lengthy email discussion it was determined that, while Harold may have presented a legitimate problem, changing how the slots work is not the solution. Harold raised another issue - 3626 - which revisits this from a different angle.
the current draft permits receive_request_service_context, receive_request, the operation, and send_reply or send_exception to all run in different threads. This is rather inconvenient, especially for OTS, where I want to to talk to an XA interface from the interception points. The problem is that XA is sensitive to the calling thread and doesn't allow me to, for example, start something in one thread and finish it in another. Now, consider the following: - The POA spec already requires preinvoke, the operation, and postinvoke to run in the same thread. - The sequence of invocations if a servant locator is present for interceptors is: 1) receive_request_service_context 2) preinvoke 3) receive_request 4) operation 5) postinvoke 6) send_reply or send_exception Of these, 2, 4, and 5 must happen in the same thread. Now, what is the likelihood that an interceptor implementation will switch context after preinvoke and before receive_request, only to have to switch back to the original thread after preinvoke and before the operation? Essentially zero, I think. It's a lot harder and a lot less efficient to do that context switch than to not do it. In other words, I don't think we would lose anything if we required that 3 and 4 must run in the same thread. Similarly, an implementation isn't going to do a context switch after 4 (or 5) and before 6, because at point 6 I still must be able to modify the reply context. (If the ORB uses a separate thread to squirt reply packets onto the wire, it might as well context switch to that reply thread *after* point 6, because until after point 6, it can't marshal anything anyway.) So, I would like to consider a change such that 2-6 must happen in the same thread. It would make OTS and other services that have some implicit dependency on thread-specific data much easier to implement, and I don't think it would constrain ORB implementations.
Portable Interceptors ptc/2000-04-05 21.7.2.7 says that resolve_initial_references is only valid during post_init. This restriction should be removed. Otherwise only local objects may be registered via register_initial_reference in pre_init. To create a non-local object and register it in pre_init one needs a POA which can only be obtained via resolve_initial_references. Prior art: We recently voted in favor of issue 3568 which made it possible to call register_initial_reference in post_init. We should adopt similar wording: if one is looking for other interceptors then resolve should be used in post_init.
It seems that most people are saying that the "services are
ORB-scoped, that's just the way CORBA works - end of story. But I
think it would be beneficial to consider what that implies to the
application program and to situations where CORBA is embedded in other
frameworks. Here is the general problem:
ORB orbX = ORB.init(...);
Foo ref1 = // get a ref that somehow ends up with a different orb
Foo ref2 = // ditto
someService1 = // get service which somehow ends up with a different orb
someService2 = // ditto
someService1.begin();
someService2.begin();
ref1.bar(...);
ref2.bar(...);
someOtherProcedure(...);
someService1.end();
someService2.end();
The workarounds of getting all the refs into the same ORB-scope as the
service is complicated when multiple services are involved. How does
one get the services to be in the same ORB-scope? It is also
complicated when one calls subroutines which may use refs with other
orbs that should participate in the service. If one doesn't own the
code then they cannot change the code to change the ref's scope.
ptc/2000-04-05 21.7.2.7 says that resolve_initial_references is only valid during post_init. This restriction should be removed. Otherwise only local objects may be registered via register_initial_reference in pre_init. To create a non-local object and register it in pre_init one needs a POA which can only be obtained via resolve_initial_references. Prior art: We recently voted in favor of issue 3568 which made it possible to call register_initial_reference in post_init. We should adopt similar wording: if one is looking for other interceptors then resolve should be used in post_init.
The current spec says that target_is_a may be invoked from send_rely, send_exception, and send_other. This appears to be impossible because these interception points run after postinvoke(), but once postinvoke() was called, the servant may no longer exist (because it is legal to call "delete servant" in postinvoke()). So, it appears that target_is_a cannot be available in these places.
This is an interceptor issue, but it is related to the INS work. The interceptor spec (ptc/2000-04-05) adds register_initial_reference to the ORB interface (section 21.8, page 21-46). The Interoperable Naming Service spec (ptc/99-12-03) adds arguments to ORB_init: -ORBInitRef and -ORBDefaultInitRef (section 4.8, page 4-44). Both affect resolve_initial_references. They do not look mutually exclusive. If they are not, then all that has to be decided is the resolution order. The INS spec says: -------------------- 4.8.4.1 Default Resolution Order The default order for processing a call to CORBA::ORB::resolve_initial_references for a given <ObjectID> is: 1. Resolve with -ORBInitRef for this <ObjectID> if possible 2. Resolve with an -ORBDefaultInitRef entry if possible 3. Resolve with pre-configured ORB settings. ------------------- Where would objects added with register_initial_references fit in this list? 0? 2.5? Consider that register_initial_reference can be called after ORB_init AND during ORB_init in the ORB Initializers (section 21.7, page 21-40). I don't know if that makes a difference, but keep it in mind.
Currently one can write code like
post_init(ORBInitInfo info)
{
PICurrent pic = (narrow ...)info.resolve_initial_references("PICurrent");
SlotId id = info.allocate_slot_id();
pic.set_slot(id, ...);
}
It would be most efficient if an implementation could wait until after
all ORBInitializer complete to allocate a fixed sized slot table.
However, the current spec makes it impossible to wait.
I do not think there is anything useful you can do via set_slot at
this point so disallowing it should not be a problem.IORInfo::get_effective_policy should allow access to the standard POA policies. In general, all policies given to an object adapter should be available regardless of what factory was used to create them. Knowing whether a POA is transient or persistent is necessary to support a Server Activation Framework.
An IORInterceptor operation which runs after IORInterceptor::establish_components is needed to "get" all the established components. Something like: void components_available( in IORInfo info ) ; It would not be legal to call IORInfo::add_ior_component nor IORInfo::add_ior_component_to_profile in IORInfo::components_available The two-phases are conceptually similar to the ORBInitializer pre_init/post_init pattern of registering references in pre_init and resolving them in post_init. <p> The complete set of established components are obtained in the form of an "IORTemplate" (see the issue by that name). <p>
This issue relates to a group of issues being raised in
interceptors-ftf in order for interceptors to support a server
activation framework.
The ability of a persistent POA and an activation daemon to exchange
IOR templates such that each can construct a valid object reference
for the other is enable by the following IDL.
/**
* A value type that captures the concept of creating
* object references according to a template.
*
* AdapterID is that part of the identity of an Object Adapter (e.g.,
* POA) that is independent of the server location.
* This would be the same as that obtained from ServerRequestInfo.
* For persistent POAs, this must be the same value each time the
* server is restarted OR the POA is activated.
*
* Object ID is the value passed to create_reference_with_id or the equivalent
* assigned in create_reference.
*
* Note that the ORB must provide an implementation for
* ObjectTemplateFactory and register it.
*/
valuetype ObjectTemplate
{
typedef sequence<octet> AdapterID ;
typedef sequence<octet> ObjectID ;
AdapterID get_adapter_id() ;
Object make_object( in ObjectID id ) ;
factory init( in Object obj ) ;
};
/**
* Extend the current IORInfo API in PI as follows.
*/
local interface IORInfoExt : InterceptorsIDL::IORInfo {
ObjectTemplate get_object_template() ;
void set_object_template( in ObjectTemplate otemp ) ;
} ;
These extensions should be incorporated into PI as follows:
- Add components_available to the IORInterceptor
- Add get/set_object_template to the IORInfo interface.
- Access to the object_template attribute is only valid in
components_available.
There is no way to determine a unique policy set. Invoking IORInterceptors on each adapter creation is therefore implicit in the current specification. However, to ensure portability, the specification should explicitly say that IORInterceptors are invoked on every adapter creation (regardless of the policy set). A Server Activation Framework needs this guarantee so that each persistent POA (re)created may exchange information with an activation daemon.
A PersistentServerId is required for servers which host POA(s) with a
persistent lifespan policy. This enables the POA to generate the same
adapter ID for the POA within a ORB with a fixed ORB ID in a server
with a particular PersistentServerId.
Proposal:
The persistent server ID is assigned by passing a
-ORBPersistentServerID= ... // some value
parameter to the ORB_init() call. In java this is done using the
org.omg.CORBA.PersistentServerID
property.
A standard mechanism for providing a persistent server port
information to an activation daemon needs to be defined. An
activation daemon needs to listen on the same port each time it is
started such that object references created by "persistent" POAs will
be valid.
Proposal:
The persistent port id is assigned by passing a
-ORBPersistentServerPort=<value>
parameter to the ORB_init() call. In java this is done using the
org.omg.CORBA.PersistentServerPort
proprty to indicate the listening port for the activation daemon.
An interceptor which gets invoked when an object adapter is destroyed is useful in the Server Activation Framework case such that POAs can remove information registered with an activation daemon.
This interceptor requirement comes from the work in CSIv2. Interceptors
are only concerned with transport-level requests, whereas security needs to
carry information around based on the user-level request which, given
retries, could span multiple transport-level requests.
To support this requirement, they need an ID for the user-level request.
They would be happy if we simply added the following to ClientRequestInfo:
readonly attribute unsigned long user_request_id;
This interceptor requirement comes from the work in CSIv2. Interceptors are only concerned with transport-level requests, whereas security needs to carry information around based on the user-level request which, given retries, could span multiple transport-level requests. To support this requirement, they need a retry mechanism. The interceptors already have a mechanism that could be used to implement retries - the LocateRequest exception. But is this appropriate? Should some other mechanism be create to distinguish retries on the same IOR from forwards to different IORs? If the retries are done often, then something other than exception should be used. Perhaps we could supply a retry method. This method would indicate to the ORB that successive interceptors' receive_other interception points should be called and that, once this transport-level request is complete, a new request should be initiated with the same user-level parameters.
This interceptor requirement comes from the work in CSIv2. Interceptors
are only concerned with transport-level requests, whereas security needs to
carry information around based on the user-level request which, given
retries, could span multiple transport-level requests.
Security could use a user_request_id (discussed in another issue) to index
into their private 'cookie jar' to transfer data that resides on a
user-level request from one transport-level request to the next. However,
this data needs to be cleaned up. If a security interceptor indicates that
a retry should occur (and stores the appropriate data), it does not know
whether that retry actually does occur. A successive interceptor may raise
an exception, for example.
What security could use is a new interception point: request_done. This
interception point deviates from the existing client-side interception
points in that it is relative to the user-level request, not the
transport-level request like the existing interception points. Therefore
it would be reasonable to place this interception point in its own
interface that implementors could mix in to their implementation if they
need it. For example:
local interface UserRequestInterceptor : Interceptor
{
void request_done ();
};
This interception point is not allowed to raise exceptions. If it raises
System Exceptions, the ORB must ignore them.
While implementing PI we found an example that may raise a contradiction in the spec. Consider the following server-side flow: A.receive_request_service_contexts is called; B.receive_request_service_contexts is called; C.receive_request_service_contexts is called; D.receive_request_service_contexts is called; A.receive_request is called; B.receive_request is called; C.receive_request is called and raises a SystemException; B.send_exception is called; A.send_exception is called; This seems to be the correct flow given the statement in 21.3.9.2 receive_request: "If it does [raise a SYSTEM_EXCEPTION], no other Interceptors' receive_request operations are called. Those Interceptors on the Flow Stack are popped and their send_exception interception points are called." However, in 21.3.10.1 Server-side Flow Rules, it is stated that "If and only if receive_request_service_contexts runs to completion is an ending point called." This "if and only if" implies that an ending point is called if "receive_request_service_contexts" runs to completion. However, if an intermediate point fails, the paragraph in 21.3.9.2 implies that send_exception is called only for those whose intermediate points returned successfully. How can we clarify this apparent conflict?
ORB_Init should only call ORB initializers when instantiating a new ORB, not every time ORB_Init is called. This is not clear in the spec. The offending verbage is in the first of the following 2 paragraphs from ptc/2000-04-05, page 21-44, between >>> and <<<: Each service that implements Interceptors will provide an instance of ORBInitializer. To use a service, an application would first call register_orb_initializer, passing in the service?s ORBInitializer. After this is complete, the application would instantiate a new ORB by calling ORB_init with a new ORB ID. >>>ORB_init calls each registered ORBInitializer. The returned ORB will contain any Interceptors that the given service requires. <<< register_orb_initializer is a global operation. An ORBInitializer registered at a given point in time will be called by all instantiating ORB_init calls that occur after that point in time. (An instantiating ORB_init call is one which produces a new ORB. In other words, one that is not passed the ID of an existing ORB.) No ORB instantiated before that point in time will be affected by that ORBInitializer. Moreover, if register_orb_initializer is called from within an initializer, the initializer registered by that call will not be called for the ORB currently being initialized. That initializer will only be invoked on an ORB instantiated at a later time. The offending sentence implies that the ORB initializers are called on EVERY ORB_Init call. It should only be called on every ORB_Init call that instantiates a new ORB. This "instantiating ORB_Init call" is defined in the next paragraph, but it should be defined and used in the first for clarity. I propose rewriting the above two paragraphs as: Each service that implements Interceptors will provide an instance of ORBInitializer. To use a service, an application would first call register_orb_initializer, passing in the service?s ORBInitializer. After this is complete, the application would make an instantiating ORB_Init call. (An instantiating ORB_init call is one which produces a new ORB. In other words, one that is not passed the ID of an existing ORB.) This instantiating ORB_Init call calls each registered ORBInitializer. The returned ORB will contain any Interceptors that the given service requires. register_orb_initializer is a global operation. An ORBInitializer registered at a given point in time will be called by all instantiating ORB_init calls that occur after that point in time. No ORB instantiated before that point in time will be affected by that ORBInitializer. Moreover, if register_orb_initializer is called from within an initializer, the initializer registered by that call will not be called for the ORB currently being initialized. That initializer will only be invoked on an ORB instantiated at a later time.
For better usability of the coding and symmetry of encoding and decoding it is nessesary to extend the information for the Codec selection. The byte order should be selectable in the request for a Codec. Rationale: To allow generation of identical encoding values for the same parameters, it must be possible to select the endianness. Proposed Resolution: Extend "struct Encoding" in section 13.7 of ptc/00-03-03 with an additional field "boolean byte_order".
Resolution: Close issue with no change. This needs a reasonable use case. That was requested but not given. Please see the issue's archive.
My suggested resolution is to change the resolution order to: The default order for processing a call to CORBA::ORB::resolve_initial_references for a given <ObjectID> is: 1. Resolve with -ORBInitRef for this <ObjectID> if possible 2. Resolve with a register_initial_reference entry if possible 3. Resolve with pre-configured ORB settings. 4. Resolve with an -ORBDefaultInitRef entry if possible Note that as Paul said in a later e-mail that this doesn't tell the whole story because the application programmer should ultimately have control over this stuff -- and be able to force the application to override command line ORBInitRef arguments. Therefore a second possible order could be: 1. Resolve with a register_initial_reference entry if possible 2. Resolve with -ORBInitRef for this <ObjectID> if possible 3. Resolve with pre-configured ORB settings. 4. Resolve with an -ORBDefaultInitRef entry if possible
Here are the scenarios needed for interceptor to have access to the
servant.
1. We want to provide security to "security unaware" applications.
2. We also want to provide security based on "security aware"
applications. (You'll see what I mean later).
We need to derive information from a particular object about the security
attributes of that object WITHOUT regard to the lifetime or persistence of
the object. (IMHO, the security specification made this extreme blunder
with the RequiredRights object, I don't want that to happen again)
We could use several things about a servant in an interceptor:
security attributes "about the servant"
owner attributes "about the owner of the servant" (new concept)
domain name "domain of the servant" (domain management).
Now, the easy thing would say, Set up a domain name and owner data base
and just associate it with an object. However, in a generic sense, there
isn't an object. If the object is persistent, what happens to this data
when the object goes to sleep? What happens if the object is destroyed?
Consitency problems all over the place.
What we need to do is "derive" the needed information, in a generic sense,
from the implementation of a servant.
It might be that you have a POA, or a series of POAs, that create
references to bank account objects. Depending on the security policy
implemented we need to classify the servants (the objects the servant is
implementing) into groups. That is, return different owner or domain names
derived from information available to the servant.
It works very cleanly this way, since all security relevant data is the
responsibility of the servant, that is if its transient transient or even
in persistent cases, we don't care. We need not make any requirements
about persistent or transient servants.
The current approach we want to take (for the POA case anyway) is to have
a POA policy associated with the creation of a POA or an interceptor. This
POA policy has intimate knowledge of the implementations of the servant.
Let me illustrate by finding a domain name for a particular servant.
We have a policy that has intimate knowledge of the groups of servants
underneath it (possibly a POA).
interface DomainNamePOAPolicy : CORBA::Policy {
DomainNameList get_domain_names(
in PortableServer::Servant serv
) raises (
IllegalServant
);
};
As a security interceptor, we might like to do the following:
RequestInfo ri; // from Interceptor
POARequestInfo pri = POARequestInfo.narrow(ri); // for use with a POA
POA poa = pri.the_poa(); // POArequestInfo specific attributes
Servant serv = pri.the_servant();
// Get the Domain Name finding policy object
DomainNamePOAPolicy dnp =
DomainNamePOAPolicy.narrow(
ri.get_server_policy(DomainNamePOAPolicyType));
DomainName[] dname = dnp.get_domain_name(serv);
.. do access control based on domain names
Fear and Loathing in ORB land:
(I fear the call to get_domain_names() might be orb
mediated, and subjected to interception?)
Anyway, please excuse the concrete implementation below, but it is just an
illustration. Say we want the DomainNamePOAPolicy to base the domain name
on some significant part of the servant. Such as grouping all the bank
accounts by the salesman under which the bank account is in his
jurisdiction. (This IS what policy is all about, of course).
class DomainNamePOAPolicy extends _DomainNamePOAPolicyImplBase {
DomainName[] get_domain_names(org.omg.PortableServer.Servant serv)
{
if (serv instanceof BankAccount) {
BankAccount ba = (BankAccount) serv;
String salesman = ba.salesman();
DomainName[] names = new DomainName[1];
names[0] = convert_salesman_to_domain(salesman);
return names;
}
throw new IllegalServant();
}
}
We want to derive security information from the attributes in the
implementation of the servant, and not store security information about a
particular object the servants represent in separate places. The latter
approach causes all kinds of consitentcy and lifecycle issues for
transient and persistent matters.
Using the policy approach as I have outlined solves most of those issues
and it is simply mandated that the policy implemented must have intimate
knowledge of the servant implementation. We don't care much about the
implementation, just the interface of it.
This situation is okay, because a security implementer would supply the
correct policies to the POA or that would provide the correct information
to a security interceptor (i.e. one that had to know about domains)
without affecting the implementation of the servant. It's all
"plug-and-play".
Does this reasoning suffice for the need to gain direct access to the
servant?
I have a general question which pertains to the recommended approach that a service writer would use to derive various interfaces from the PI-defined interfaces (e.g. ORBInitializer, IORInterceptor, etc.). I'm primarily interested in the C++ mapping since I'm trying to implement PI in a C++ ORB. As a means of providing the answer, would it be possible for someone to post an example of how a service writer would implement an ORBInitializer in order to register a request interceptor? My main curiousity would be how the user would define his own ORBInitializer-derived interface (would it be in IDL or straight C++?), how his "implementation" class would be declared/defined, etc. I don't see any examples of this in the spec (I know, the spec should not be bogged down with such details :-) ), but if we're going to provide "portable" interceptors we need to make sure that the user's code can be "portable", right? Anyway, I would appreciate it if someone could provide an example which outlined the various classes that would be involved (some of the classes will be the result of emitting the PI idl, and other classes will belong to the user).
LOCATION_FORWARD_PERMANENT was deprecated by the interop 2Kplus, issue
1486. It was included in vote 2:
ftp://ftp.omg.org/pub/interop/interop2kplusvote2.htm
The results are somewhere in: ftp://ftp.omg.org/pub/interop
However, the portable interceptor specification ptc/2000-04-05
specifies a ForwardRequest exception with a boolean permanent field.
This field and all references to it should be removed from the
interceptor specification.
This is issue x in the original report
The summary of issue 3660 (IORInfo::get_effective_policy access
to POA policies ) says:
"The standard POA policies should be available via
IORInfo::get_effective_policy"
The resolution says:
Exact text to be determined as a new issue if this issue passes.
I think we could agree to add text (like that suggested by Bob) to say
policies passed to create_POA are available as an editorial part of
3660.
This would result in text like the following:
-------------------------
An ORB service implementation may determine what server side policy of
a particular type is in effect for an IOR being constructed by calling
the get_effective_policy. The returned CORBA::Policy object shall
only be a policy whose type was registered via
ORBInitInfo::register_policy_factory (see section 21.7.2.12,
register_policy_factory on page 21-43) AND policies defined in module
PortableServer.
If a policy for the given type was not registered via
register_policy_factory or is not defined in module PortableServer,
this operation will raise INV_POLICY with a standard minor code of 2.
-------------------------
It seems that no one wants the registration bits any longer.
And, in the process of looking at this, it was discovered that the
text does not say what happens when the given policy is not in effect.
Removing the bits about policy factory registration and adding the
policy not in effect bits seems to go beyond the scope of 3660.
So, I think we need to vote on an issue for the exact text of
get_effective_policy.
I propose:
-------------------------
An ORB service implementation may determine what server side policy of
a particular type is in effect for an IOR being constructed by calling
the get_effective_policy operation. When the IOR being constructed is
for an object implemented using a POA, all Policy objects passed to the
PortableServer::POA::create_POA call that created that POA are
accessable via get_effective_policy.
If a policy for the given type is not known to the ORB, then this
operation will raise INV_POLICY with a standard minor code of 2.
Parameters
type
The CORBA::PolicyType specifying the type of policy to return.
Return Value
The effective CORBA::Policy object of the requested type.
If a policy for the given type is known but that policy is not in
effect, then this operation will return a nil object reference.
-------------------------
I'll get an official vote issue document posted right away.
Are exceptions permitted from pre_init() and post_init() calls? I seem to remember that we discussed making this illegal -- however, I don't notice any verbage in the spec. The problem is if it's illegal to raise exceptions in pre_init and post_init there is no sensible way for an ORB service to indicate to the application that initialization failed. The best that can be done is to call exit() or log an error message.
Are there any synchronization guarantees of pre_init and post_init calls? It would be useful for many applications if the implementation of the ORBInitializer can hold state between pre_init & post_init calls -- but currently this isn't easily possible because there are no synchronization guarantees on the interface hence concurrent calls to pre_init and post_init can occur. I'd actually like a fairly strong guarantee such that calls to both pre_init and post_init are guaranteed to be atomic. That is something like the following (I don't know how to say this sensibly in English ;) global_mutex.lock(); initializer -> pre_init() initializer -> post_init() global_mutex.unlock();
Resolution: Incorporate change and close issue. Note that the additional text is written to allow an ORB implementation to run pre_init operations in parallel followed by post_init operations in parallel. It just states that you cannot start executing post_init until all pre_init calls have completed.
All pages of ptc/00-08-06 reference Codec and CodecFactory as being in module IOP - EXCEPT section 21.10 (the consolidated IDL). There is says IOP_N. At one time IOP_N was a placeholder until the exact version of module IOP was determined. Was a determination made that IOP was the proper module/version?
ptc/00-08-06 table 4-1, page 63 has a mistake in its list for TRANSIENT minor codes. It lists the number 2 for both "No usable profile in IOR" and "Request cancelled". The value for Request cancelled should be 3 (see same doc section 21.3.7.2 page 211 second paragraph ). Also, "Request cancelled" is misspelled.
Resolution: Close issue with no change. Note, ptc/01-03-04, which was the basis for CORBA 2.5, does not contain this error. It was fixed editorially. Therefore no further change is necessary.
We have been looking at sending fragmented request and reply messages and fragmented replies in particular seem to have some interaction with the interceptors. There would seem to be several performance and/or space benefits in being able to send each fragment of a message as it is created rather than having to build the complete message and chopping it up only as it is sent across the wire. However the send_reply/send_exception interceptor seems to prevent this. Since the interceptor is able to alter service contexts (which appear right at the start of a message) and since we cannot drive the send_reply/send_exception interceptor until the entire reply message has been marsalled (as only then can we know for sure whether we have an exception or not) this seems to rule out sending any fragments until the entire reply has been built.
Resolution: Close issue with no change. Several ORB vendors have implemented PI and GIOP 1.2 fragmentation successfully without having the problem noted in this issue.
Do the client & server side interceptors see LocateRequest messages? I think they should not. The reason why this is an interesting issue is that although I think that the client & server side interceptors should not see locate request messages, servant managers do see them. (although I'm not sure if this is spelled out in the spec -- another issue?). That means that there are requests which user-code sees which interceptors do not.
I think they should not. Any other opinions? I sent this message to early: The reason why this is an interesting issue is that although I think that the client & server side interceptors should not see locate request messages, servant managers do see them. (although I'm not sure if this is spelled out in the spec -- another issue?). That means that there are requests which user-code sees which interceptors do not.
What should happen with Interceptors when Java stubs take the "local
optimized" path? This can happen when the client and server both share the
same ORB and, if so, the client can make a direct method call to a servant
object. The stubs contain code like this:
public int ExampleMethod(int i)
{
if ( !this._is_local() ) {
... // Non-local case ...
else {
org.omg.CORBA.portable.ServantObject so =
_servant_preinvoke("ExampleMethod",_opsClass);
if (so == null) ... // Non-local after all ...
try {
((ExampleOperations)_so.servant).ExampleMethod(i);
return;
} finally ( _servant_postinvoke(_so); }
}
}
Should interceptors be driven when this local route is taken? It is an
ORB-mediated invocation so the answer ought to be yes, but I'm not sure it
really makes a lot of sense. Since client and servant are running in the
same thread interceptors would not be needed to transfer thread-context
around. And since there is no actual GIOP request/repsonse flow, there is
no request_id or service_contexts or many of the other things interceptors
normally deal with. This could all be simulated but then the "local
optimized" path would become a lot less optimized, and where should the
interception points be driven? The _servant_preinvoke() would probably
drive send_request, receive_request_service_contexts and receive_request,
but the return set (send_reply/send_exception and
receive_reply/receive_exception) look harder; _preinvoke is too early and
_postinvoke is really too late.
Of course a simple solution from an implementation point of view is just to
make the _is_local() test always return false if we have request
interceptors registered. But this seems to be avoiding the issue.
Currently, ORBInitInfo.resolve_initial_references() returns void. This is incorrect. Since its semantics is meant to be same as orb->resolve_initial_references(), it should return Object instead.