Issue 2772: Potential deadlock with POA::deactivate_object()
Issue 3097: Custom Value Marshaling Issue
Issue 3459: DynValue & custom valuetypes ORB mediation for servant managers, references for servant managers?
Issue 3674: Polymorphic Valuetypes and the DII
Issue 3907: Issue: CSIv2 Identity Assertion
Issue 4065: How does an ORB implement Object::get_policy for PI defined policies?
Issue 4137: Implications of any/valuetype marshalling
Issue 4169: Avoiding RSC/TSC copy on server side
Issue 5214: Proposal for extension to CosNaming
Issue 5231: New issue: ForwardRequest(<local object>) Replace deprecated anonymous type declarations?
Issue 5266: ForwardRequest is impossible to detect in clients
Issue 5439: processing TaggedComponents within an IOR
Issue 5467: How does DynValue handle derived valuetypes?
Issue 5621: messaging router issue
Issue 5624: Spec doesn't make clear what is valid mix of policies and what is invalid
Issue 5662: Messaging Routing Protocol is broken for GIOP 1.0 & 1.1 potential name clash with Messaging type-specific poller timeout argument
Issue 5781: What is the RSC when using a PersistentPoller
Issue 5856: Bad text in 22.6 mandates Routing for sendc/sendp
Issue 5880: Clarification on multi-threaded codeset negotiation
Issue 5892: restriction of where a valuetype chunk can end
Issue 5895: Problem with ServerRequestInterceptor::receive_request and DSI
Issue 5899: rules for marshalling ValueBoxes
Issue 5939: ValueMembersSeq
Issue 5941: valuetype fragmentation ambiguous
Issue 5952: BNF changes
Issue 6007: Mapping from -ORBxxx to Java properties does not work for -ORBInitRef
Issue 6050: 15.3.3 - codesets must be "explicitly defined"
Issue 6283: CodeSet and CSIv2 Negotitaion
Issue 6285: Change new GIOP Negotiate Session Message to Firewall Specific
Issue 6287: Chapter/section: 15.4.2.2 "Request Body"
Issue 6314: GIOP Conformance and Interceptors
Issue 6318: valuetypes and local interfaces
Issue 6391: Interface Introspection
Issue 6424: Section 22.2.4.6 interface RelativeRoundtripTimeoutPolicy
Issue 6899: CORBA 3.02, page 11-25, section 11.3.6
Issue 7340: module SendingContext
Issue 7592: An extension of IOR to protect target objects Nature
Issue 7730: Codec Interface Deficiencies
Issue 7890: methods on the POA
Issue 7891: Make a typedef for the POA id new
Issue 7892: Add a typedef for the POAManager id
Issue 7893: change in the POAManager
Issue 7896: argument of the set_servant call has a small typo
Issue 7900: omission from the OMG --Trader spec
Issue 7955: The POA state inactive is not used consistent.
Issue 7978: CORBA 3.0.3 ch. 3.4 OMG IDL Grammar
Issue 8221: Section: 4.3.13
Issue 8230: Appendix A
Issue 8244: Code Set Conversion on Operations
Issue 8586: Moving *Seq typedefs into ORB chapter
Issue 8618: Minor code ambiguity
Issue 8629: Typo in sections 22.10.1.1 and 22.10.1.2
Issue 8630: Section: 7.4
Issue 8631: Section: 13.6.2
Issue 8632: Section: 4.2
Issue 8633: Section: 4.2 (02)
Issue 8783: update the spec to not used anonymous types
Issue 8843: Section: 21.7
Issue 8844: Section: 21.9.1
Issue 8856: Section: 21.4.3.1
Issue 8860: Section: 4.5.2
Issue 8862: Section: 21.3.14.11
Issue 8864: Section: Appendix A
Issue 8874: Page: 21-5
Issue 8879: Page: 9-1
Issue 8881: Page: 7-7
Issue 8929: NVList Section: 7.5
Issue 8969: Allowing Mutual Recursion for IDL Structures
Issue 8985: Section: Chapter 11
Issue 8986: Section: Chapter 9, Chapter 5
Issue 9016: Section: 11.3.9
Issue 9075: Section: 22.16/
Issue 9082: Section: 22.11.1
Issue 9112: Page: 21-43
Issue 9118: Page: 56..64
Issue 9140: FullInterfaceDescription and base_interfaces question
Issue 9460: Section: 11.3.9.16
Issue 9618: CORBA Exceptions
Issue 10558: Allowing mutual recursion for IDL structs - clarification needed
Issue 10817: Section: 21.3.13
Issue 11161: Section: 13.6.10.1
Issue 11332: Section: 15.4.2/16.4.1
Issue 11514: Proposal to change PortableInterceptor::ReplyStatus to a real enum
Issue 11515: Proposal to change PortableInterceptor::AdapterState to a real enum
Issue 11525: Third line of 23.1.3.4, ACTIVE must be bold
Issue 12229: definition of Invalid Policies changed
Issue 12230: mention of (deprecated) function get_implementation removed from text
Issue 12376: Section: Part 2, Chapter 11 - MIOP
Issue 2772: Potential deadlock with POA::deactivate_object() (corba-rtf)
Click here for this issue's archive.
Nature: Uncategorized Issue
Severity:
Summary: The draft CORBA 2.3 spec (ptc/99-03-07) does not deal with a potential deadlock situation. If an object is explicitly deactivated with POA::deactivate_object(), the object remains in the active object map until all operations pending on the object have completed. Any attempts to reactivate the object (implicitly via a ServantActivator, or explicitly via activate_object_with_id()) must block until the pending invocations have completed. However, if a servant's implementation of an object deactivates the object and then (directly or indirectly through a call to another collocated object) reactivates the object, the invocation will deadlock.
Resolution:
Revised Text:
Actions taken:
June 28, 1999: received issue
Discussion:
Issue 3097: Custom Value Marshaling Issue (corba-rtf)
Click here for this issue's archive.
Source: Camros Corporation (Mr. Jeffrey A. Marshall, jam@camros.com)
Nature: Uncategorized Issue
Severity:
Summary:
Due to the way that custom values are marshaled it is nearly impossible for a bridge (or other process) to process/forward GIOP messages which contain custom marshaled values (which the bridge has no compile/run-time knowledge of). The main issue is that the "alignment" of the custom marshaled data is unknown, other than the data will always start on a four byte boundry due to the presence of chunking. Should/could the value encoding format be changed to enforce eight byte alignment for all custom marshaled data (chunks)? This would allow bridges and other tools to process->[store]->forward messages containing custom values.
The CORBA 2.3.1 specification does not cover the interaction between the DynValue interface and custom valuetypes. I frankly don't see any way that the DynValue interface can possibly correctly handle a custom valuetype when the ORB does not have a factory for the type. It is theoretically possible for DynValue to properly work with a known custom type, but the implementation strategy could not be based on parsing the marshalled form of the valuetype. So, there are two issues that need to be addressed: 1. Should DynValue handle custom valuetypes at all? 2. For the set of custom valuetypes that it cannot handle, what exceptions should be raised by each operations?
Using the static invocation interfaces, it is possible to receive a valuetype that derives from the one declared in an operation, as long as a valuetype factory is known in the receiver (truncation is not the issue here). The same is not possible at the DII: When creating the request, the caller must indicate what type it expects, by forming a named value. Conceptually, the typecode in the named value should be the typecode of the base of all acceptable value types. However, if the ORB receives a derived type, it has no means of unmarshalling it - even if the application has knowledge about the derived type. What is missing is an interface to make typecodes of value types known to the ORB; with those, the ORB could then understand the CDR of the valuetype, and create a DynAny when asked to.
Issue on Document orbos/2000-08-04, CSIv2 Joint Submission
Document: orbos/2000-08-04, CSIv2 Joint Submission
Subject: Identity Assertion of X.501 Distinguished Name is not good enough
Severity: Critical
Summary:
The Identity Token union contains a branch that is labled
X501DistinguishedName. A single DN is insufficient to identify an entity.
A path of X501Distinguished Names is needed instead. Also, other concerns
about naming types are raised.
Discussion:
An X.501 Distinguished Name is insufficient to identify a single entity.
The name must be accompanied by the name of its defining authority. In the
case of public key certificates, the names certificate authority must be
included.
The chain of DNs in this manner must be included up to a root authority
to have any definitive meaning.
This approach will be consistent with the client sending a X.509
Certificate Chain. A DN path is actually defined by the certificate chain.
Furthermore, the DN path should only come from an authority that is
acceptable to the server, whether it be a DN path, or an X.509
Certificate Chain.
The IOR should list the acceptable authorities and their name types.
It is becoming more an more evident that we must invent GSS_NT_Export_Name
types for X.509 Certificate Chain and X.501 DN path.
The SAS_ContextSec structure should list, instead of the naming types,
the naming authorities!
We shall assume that the name types of the asserted identities shall be
the same as the name types of listed naming authorities in the IOR.
This is the only way this procedure can work Interoperable and without
the client Guessing what it should do.
Suggestions:
An OID for an X.509 Public Key Certificate Chain shall be defined for a
GSS Export Name, and its encoding will be a ASN1 sequence of and X.509
certificate with the least significant certificate first.
An OID for an X.501 Distinguished Name Path shall be defined for a GSS
Exported Name, and its encoding shall be an ASN1 sequence of an X.501
Distinguished Name with the least significant name first.
To avoid having the target put a whole certificate chain in its IOR,
a new OID shall be allocated in which its GSS Exported Name encoding is a
X.501 DN path, but stipulates that the client should send a certificate
chain from that named authority. This GSS Exported Name shall only be
used in IORs and not for transmission in the Identity Token.
typedef Security::GSS_NT_ExportedName NamingAuthority;
struct CompoundSecMech {
Security::AssociationOptions target_requires;
IOP::TaggedComponent transport_mech;
sequence<ServiceConfiguration> privilege_authorities;
sequence<NamingAuthority> naming_authorities;
};
The description for Object::get_policy (in the Core, section 4.3.7.1)
states:
"The get_policy operation returns the policy object of the specified
type (see Policy Object on page 4-32), which applies to this object. It
returns the effective Policy for the object reference. The effective
Policy is the one that would be used if a request were made."
For a policy defined by PI, I don't see anyway for the ORB to implement
this operation correctly, since there isn't any way for it to know how
to properly resolve any client override policies with the policy
information stored in the IOR.
When a invocation is actually in process, the ClientRequestInterceptor
can use the information available in the ClientRequestInfo interface to
get the client override and the IOR policy data and do the correct
resolution before continuing with the request. However,
Object::get_policy() needs to do the same type of thing, but it has no
invocation context to do it in.
I think the same problem also applies to the implementation of
ClientRequestInfo::get_request_policy().
I think we need a new interception point to do this work. Something
like:
local interface PolicyInterceptor {
any determine_effective_policy(in PolicyInfo pi);
};
local interface PolicyInfo {
readonly attribute Object target;
readonly attribute Object effective_target;
readonly attribute IOP::TaggedProfile effective_profile;
IOR::TaggedComponent get_effective_component (in IOP::ComponentId
id);
IOP_N::TaggedComponentSeq get_effective_components (in
IOP::ComponentId id);
};
If this turns out to be an acceptable solution, then we should also
change ClientRequestInfo to:
local interface ClientRequestInfo : RequestInfo, PolicyInfo {
...
};
and remove the redundant operations.
RE: CCM chapters document [orbrev] 99-10-04, section 61.6.2, page 61-45. The document citation indicates that the integrity of the valuetype -- that is, the received marshalled state -- is to be preserved in an ORB-mediated operation, even if that valuetype cannot be unmarshalled, either partially (truncated) or at all. If this value is then passed to another operation, the original marshalled state is to be transmitted. This preserves the transmitted object in its entirety, regardless of local implementation concerns. This is obviously necessary for bridges or event processing, such as through the notification service. So the question arises, what happens if you have a partial (truncated) unmarshall and the recipient application changes the local state of the valuetype through its attributes or local operations? How can/will you even know the state was changed? Do you ignore the changes and send the originally received marshalled stream, send only the new valuetype even though it is a truncation of the original, or "merge" the new values for the unmarshalled part followed by the original appended data for the truncated part? Should this third option be possible through an explicit ORB call -- that is, the application is responsible to identify the change in state to the ORB? I assume that the semantics of "truncatable" must come to include the understanding that data in the truncatable portions may not be contextually dependent on the inherited parent of the valuetype. As a further question, is there a reason why this semantic interpretation should not be extended to be a general requirement rather than only with respect to transmission of anys? My experience has found that passing anys tends to be expensive and is avoided where it can be. A more general interpretation permits transmission of a comprehensive data structure among intermediate agents that only use (unmarshall) the information they need.
The integrity of value types contained in anys is a requirement on the ORB core, and an appropriate paragraph should be added to the Value Type Semantics chapter. This requirement is not limited to Components. The paragraph in the Components specification that mentions this requirement should be removed. This issue should then be moved to the Core RTF.
During the interceptor FTF we changed the server-side threading requirements such that all server-side points run in the same thread as the ServantManager and servant except receive_request_service_contexts. We attempted to update 21.4.4.4 "Request Scope vs Thread Scope" accordingly but knew we screwed the picture and wording up. So we punted to the RTF. The main problem with the current wording is that is forces a copy of of TSC/RSC before the servant manager and then receive_request are called. This is necessary because 21.4.4.5 item 5 says: "The receive_request points may modify the RSC, but this no longer affects the TSC." The only way to make RSC identical to TSC in receive_request with respect to reading but also have them be independent with respect to writing is to make a copy (which could be optimized to copy-on-write, but why?). I suggest we just state they are equivalent after receive_request_service_contexts. Here is a proposed revision to ptc/00-08-06 along these lines. Comments? Harold 21.4.4.4 Request Scope vs Thread Scope ... On the server-side, the request scope PICurrent is attached to the ServerRequestInfo and follows the request processing. It is logically equivalent to the thread scope PICurrent after the list of receive_request_service_contexts interception points are processed. 21.4.4.5 Flow of PICurrent between Scopes 5. The ORB logically makes the RSC equivalent to the server-side TSC after the receive_request_service_contexts points are processed and before the servant manager is called. This TSC is within the context for both the receive_request points, the invocation of the servant manager, and the invocation of the target operation. The receive_request points are called. These points have access to the RSC. Modifying the RSC at this point makes corresponding modifications on the TSC. Since these points execute in the same thread as the target operation invocation, these points may modify the server-side TSC which makes corresponding modifications on the RSC. 6. After the receive_request points are called, control transfers to the server threads which may also read and write this server-side TSC. Any modifications to the TSC makes corresponding modifications on the RSC. 7. <No change> 8. <DELETE THIS ITEM> 9. The send interception points have access to the RSC (and the equivalent TSC) from which they may populate the reply service context list. After the invocation result is sent back to the client, the server-side RSC is logically destroyed. ... The picture would also need updating, but let's agree on wording first.
Since there doesn't appear to be a CosNaming mailing list this seems like as good a forum as any this discussion.
It has long struck me that the use of CosNaming for JNDI in J2EE applications creates a significant outage in being able to bind and retrieve objects that are not remote (see the EJB 2.0 spec for details). In JNDI you can bind pretty much anything that is Remote (aka an Object reference) or Serializable (aka a valuetype), however CosNaming only allows you to do the former.
One easy way to solve this would be to create a new NamingContext extension that allows one to bind and resolve Any's. This is in keeping with the Java-to-IDL spec's treatment of untyped Java objects and at the same time would not compromise non-java implementations. For JNDI it would only be necessary to support Any's containing:
1. Object references
2. valuetypes
3. valueboxes
An exception could be thrown for any other types. The candidate interface might look something like this:
module CosNaming {
interface NamingContextAny : NamingContextExt {
exception TypeNotSupported {};
void bind_any(in Name n, in any obj)
raises (NotFound, CannotProceed,
InvalidName, AlreadyBound, TypeNotSupported);
void rebind_any(in Name n, in any obj)
raises(NotFound, CannotProceed, InvalidName, TypeNotSupported);
any resolve_any (in Name n)
raises (NotFound, CannotProceed, InvalidName);
any resolve_str_any(in StringName n)
raises (NotFound, CannotProceed,
InvalidName, AlreadyBound);
};
};
The implementation of this interface in Java is trivial, although perhaps less so in other languages. Whether or not that matters is open to question.
The Portable Object Adapter and Portable Interceptors both are able to raise a ForwardRequest exception to allow redirection to another object. What happens if the ForwardRequest is to a local object? Is this even possible? Should it be allowed? I suggest we change the specification to make this illegal.
REQUIREMENT
To be able to use interceptors, and in particular ForwardRequest, in a client to perform active, per-request, load-balancing.
PROBLEM
It is not possible to detect in an interceptor whether ForwardRequest has previously been thrown for the same client request. Thus it is possible for a client to go into an infinite loop throwing ForwardRequest.
DISCUSSION
The basic problem is that although for a single client request the request-scoped PICurrent is shared across across interceptor invocations - even when ForwardRequest is thrown - it is not possible to *modify* this information in an interceptor to indicate to a future invocation that the invocation has been seen. The two relevant parts of the spec here are:
21.3.6.5
For retries, depending on the policies in effect, a new request may or may not follow
when a retry has been indicated. If a new request does follow, while this request is a
new request, with respect to Interceptors, there is one point of correlation between the
original request and the retry: because control has not returned to the client, the request
scoped PortableInterceptor::Current for both the original request and the retrying
request is the same (see Chapter 21, Portable Interceptors on page 21-32).
21.4.2
Before an invocation is made, PICurrent is obtained via a call to
ORB::resolve_initial_references ("PICurrent")
From within the interception points, the data on PICurrent that has moved from the
thread scope to the request scope is available via the get_slot operation on the
RequestInfo object. A PICurrent can still be obtained via
resolve_initial_references, but that is the Interceptor's thread scope PICurrent.
See section 21.4.4.4, Request Scope vs Thread Scope on page 21-36 for a detailed
discussion of the scope of PICurrent.
Thus modifications to the thread's PICurrent are lost on retries and modifications to the request's PICurrent are not possible.
PROPOSED RESOLUTION
I have made several different attempts at coming up with a portable way of solving this problem without changing the spec, but have failed. It seems to me that it really should be possible for the interceptor to know that a retry is in effect and I can think of a number of different solutions to this:
1. add:
void set_slot (in SlotId id, in any data) raises (InvalidSlot);
to RequestInfo. This would allow interceptors to transfer information between invokes of the same client request and thus a retry could be detected.
2. Add a new function to RequestInfo to indicate that a forward is in operation. The minimalist fix here would be to allow forward_reference() to be accessed in send_request() as well as in receive_other(). i.e. returning the object from the previous ForwardRequest if that has been thrown.
I'm ambivalent about which of these is best but for the sake of simplicity I'm going to plump for (1) because this is already allowed in ServerRequestInfo.
So:
- Change the IDL in 21.3.12 to include
void set_slot (in SlotId id, in any data) raises (InvalidSlot);
- After 21.3.12.12 move in the text from 21.3.14.6
- Change the IDL in 21.3.14 to remove set_slot()
The overhead of processing TaggedComponents within an IOR becomes
significant when done many times, as in the case of J2EE
implementations where multiple interceptors are used.
The definition of IORs in the IOP module is intended to support
transmission and interoperability, rather than efficient access to the
local, ORB specific, internal structure.
I would like to propose that an abstract model of an IOR is introduced
which recognises that many of the constituent parts of IOR profiles are
identical for different objects, along the following lines:-
- an IOR has a type ID string, and contains TaggedProfile instances
- a TaggedProfile has an ID and data
- an IIOPProfile is a TaggedProfile; it is composed of an
IIOPProfileTemplate and an object ID.
- an IIOPProfileTemplate has IIOP addressing information, and contains
TaggedComponents.
- a TaggedComponent has an ID and data
- a TaggedComponentFactory creates a TaggedComponent
- a TaggedProfileFactory creates a TaggedProfile
with corresponding IDL definitions that allow the language bindings
to optimise conversion between transmission and internal IOR formats
to provide a performant and natural interface for IOR access.
Rationale:
In Java, for example, it should be possible to manipulate IOR
TaggedProfiles and IIOPProfileTemplate TaggedComponents using the
facilities of the Java collections framework, or at least some
equivalent facility that is a natural Java idiom.
Templates can be used to create IIOPProfiles because the basic object
adapter model for object creation is to establish many of the properties
of an IOR when the object adapter is created.
- This has been present for the POA essentially from the beginning, since
policies can only be passed to create_POA, and cannot be changed on an
existing POA.
- The Portable Interceptors work has also made this clear, since the IOR
interceptor establish_components method, which is the only time that
user code can add tagged components to an IOR, is only guaranteed to
be called once for each distinct set of server policies i.e need only
be run when an object adapter is created.
- It is also likely that more than one object within an adapter will
map to a TCP endpoint.
TaggedProfile and TaggedComponent are intended as frameworks that may be
extended to support application defined tagged profiles and components.
To support this it is necessary to be able to register TaggedProfile and
TaggedComponentFactory instances with an ORB, in which case any IOR
unmarshalled by that ORB instance will use the registered factory
to unmarshal the tagged profile or component.
Since there has already been quite a bit of discussion about this in the
Java RTF, here is a proposal for review:-
Proposal:
- add the following sections after the IOR Interceptor Overview:-
21.5.2 An Abstract Model for IORs
To support efficient access to IORs, avoiding repeated marshaling and
demarshaling of IOR components, it is helpful to have an abstract model
of the, ORB specific, local representation of an IOR.
Recognising that many of the constituent parts of IOR profiles are
identical for different objects allows the following model to be
defined:-
- an IOR has a type ID string, and contains TaggedProfile instances
- a TaggedProfile has an ID and data
- an IIOPProfile is a TaggedProfile; it is composed of an
IIOPProfileTemplate and an object ID.
- an IIOPProfileTemplate has IIOP addressing information, and contains
TaggedComponents.
- a TaggedComponent has an ID and data
- a TaggedComponentFactory creates a TaggedComponent
- a TaggedProfileFactory creates a TaggedProfile
21.5.3 Local IOR Interfaces
The following interfaces provide access to the data within a local IOR
using this model.
TaggedProfile and TaggedComponent are generic interfaces. Users of the ORB
may create implementations of them. Corresponding factories may be
registered with the IORFactory.
The IORFactory is obtained through a call to
ORB::resolve_initial_references ("IORFactory") and may also be used to
obtain an IOR for an Object.
An ORB must return all tagged profiles in an IOR through the IOR
getProfiles operations. The ProfileIterator interface allows a client
to iterate through the TaggedProfiles using the next operation.
Those profiles whose ids have a registered TaggedProfileFactory will
be made available in the form returned by the registered factory's
TaggedProfileFactory create operation, which must return a subtype of
TaggedProfile.
An ORB will provide a TaggedProfileFactory implementation for the
IIOPProfile.
Profiles with ids for which no TaggedProfileFactory has been registered
will be made available as instances of a generic ORB implementation of
TaggedProfile.
Similarly, an ORB must return all tagged components in an IIOP profile
through the IIOPProfile().getTemplate().getComponents() operations.
The ComponentIterator interface allows a client to iterate through the
TaggedComponents using the next operation.
Those components whose ids have a registered TaggedComponentFactory
will be made available in the form returned by the registered factory's
TaggedComponentFactory create operation, which must return a subtype of
TaggedComponent.
Components with ids for which no TaggedComponentFactory has been
registered will be made available as instances of a generic ORB
implementation of TaggedComponent.
module PortableInterceptor {
local interface TaggedComponent {
readonly attribute IOP::ComponentId component_id;
readonly attribute CORBA::OctetSeq component_data;
IOP::TaggedComponent convert();
};
local interface ComponentIterator {
TaggedComponent next();
boolean has_next();
};
local interface TaggedProfile {
readonly attribute IOP::ProfileId profile_id;
readonly attribute CORBA::OctetSeq profile_data;
IOP::TaggedProfile convert();
};
local interface ProfileIterator {
TaggedProfile next();
boolean has_next();
};
local interface IOR {
readonly attribute string type_id;
ProfileIterator get_profiles ();
ProfileIterator get_profiles_by_id (in IOP::ProfileId profile_id);
};
local interface IIOPProfileTemplate {
readonly attribute IIOP::Version iiop_version;
readonly attribute string host;
readonly attribute unsigned short port;
ComponentIterator get_components();
ComponentIterator get_components_by_id (in IOP::ComponentId id);
};
local interface IIOPProfile:TaggedProfile {
readonly attribute CORBA::OctetSeq object_key;
readonly attribute IIOPProfileTemplate profile_template;
};
local interface TaggedComponentFactory {
readonly attribute IOP::ComponentId factory_id;
TaggedComponent create_tagged_component
(in CORBA::OctetSeq component_data);
};
local interface TaggedProfileFactory {
readonly attribute IOP::ProfileId factory_id;
TaggedProfile create_tagged_profile
(in CORBA::OctetSeq profile_data);
};
local interface IORFactory {
IOR create_ior (in Object obj);
void register_tagged_profile_factory (in TaggedProfileFactory tpf);
void register_tagged_component_factory (in TaggedComponentFactory tcf);
};
};
21.5.3.1 IOR Factory Interface
create_ior
Return an IOR relating to the given Object.
If create_ior is invoked when the object reference is not bound,
standard system exception BAD_INV_ORDER with minor code n will be
raised.
register_tagged_profile_factory
Register a TaggedProfileFactory to create TaggedProfiles with the id
returned by the given factory's getId method. If a TaggedProfileFactory
already exists for the given id, standard system exception
BAD_INV_ORDER is raised with a standard minor code of n+1.
Instances of this interface may be defined by users to support custom
tagged profiles.
register_tagged_component_factory
Register a TaggedComponentFactory to read TaggedComponents with the id
returned by the given factory's getId method. If a
TaggedComponentFactory already exists for the given id, standard system
exception BAD_INV_ORDER is raised with a standard minor code of n+2.
Instances of this interface may be defined by users to support custom
tagged components.
21.5.3.2 IOR Interface
This interface gives access to a local representation of an
IOP::IOR.
type_id
The type id string from the IOR.
get_profiles
Returns an iterator over the TaggedProfiles within the IOR.
get_profiles_by_id
Returns an iterator over the TaggedProfiles with the given
Profileid.
21.5.3.3 TaggedProfile Interface
This interface gives access to a local representation of an
IOP::TaggedProfile.
profile_id
This attribute is the identifier for this TaggedProfile.
profile_data
This attribute is the data from the TaggedProfile. It is
normally a CDR encapsulation.
convert
Create an IOP representation of this TaggedProfile
21.5.3.4 TaggedComponent Interface
This interface gives access to a local representation of an
IOP::TaggedComponent.
component_id
This attribute is the identifier for this TaggedComponent.
component_data
This attribute is the data from the TaggedComponent. It is
normally a CDR encapsulation.
convert
Create an IOP representation of this TaggedComponent.
21.5.3.5 TaggedProfileFactory Interface
factory_id
This attribute is the identifier of profiles created by this
TaggedProfileFactory.
create
Create a TaggedProfile from the given profile_data.
21.5.3.6 TaggedComponentFactory Interface
factory_id
This attribute is the identifier of components created by this
TaggedComponentFactory.
create
Create a TaggedComponent from the given component_data.
21.5.3.7 ProfileIterator Interface
next
Returns the next TaggedProfile in the iteration. If next is called
after the last TaggedProfile has been returned, BAD_INV_ORDER will
be raised with a standard minor code of n+3.
If an IOR is modified in between calls to next, the behavior of
further calls to next is implementation dependent.
has_next
Returns true if the iteration has more elements. In other words,
returns true if next would return an element rather than throwing
an exception.
21.5.3.8 ComponentIterator Interface
next
Returns the next TaggedComponent in the iteration. If next is called
after the last TaggedComponent has been returned, BAD_INV_ORDER will
be raised with a standard minor code of n+3.
If a profile is modified in between calls to next, the behavior of
further calls to next is implementation dependent.
has_next
Returns true if the iteration has more elements. In other words,
returns true if next would return an element rather than throwing
an exception.
21.5.3.9 IIOPProfile Interface
object_key
This attribute is the Object key contained in this IIOPProfile.
profile_template
This attribute is the IIOPProfileTemplate associated with this
IIOPProfile.
21.5.3.10 IIOPProfileTemplate Interface
iiop_version
This attribute is the GIOP version of this profile. If the major
value is 1 and the minor value is 0, this profile cannot contain
any TaggedComponents.
host
This attribute is the host name string of this IIOPProfileTemplate.
port
This attribute is the port number of this IIOPProfileTemplate.
get_components
Return an iterator over the TaggedComponents within the
IIOPProfileTemplate.
get_components_by_id
Returns an iterator over the TaggedComponents with the given
ComponentId.
In current Section 21.5.3:
- add the following after the ORBInfo Interface
local interface IORInfo_3_n:IORInfo {
ProfileIterator get_profiles ();
ProfileIterator get_profiles_by_id (in IOP::ProfileId profile_id);
};
- add the following sections:
21.5.3.4 get_profiles
Returns an iterator over the TaggedProfiles within the IOR.
21.5.3.5 get_profiles_by_id
Returns an iterator over the TaggedProfiles within the IOR with the
given Profileid.
Parameter Description
profile_id The IOP::ProfileId of the profiles in the iteration
to be returned.
- add the IORFactory to the list of reserved ObjectIds for
resolve_initial_references in section 4.5.2I just noticed that the description of DynValue is totally silent on the
issue of derived valuetypes.
Here's an example to set things up:
// IDL
valuetype A {
public short s;
};
valuetype B {
public long l;
};
struct S {
A an_a;
};
// C++
DynamicAny::DynFactory df = ...;
B *b = ...;
S my_s;
CORBA::Any my_any;
s.an_a = b;
my_any <<= s;
DynamicAny::DynAny_var da = df->create_dyn_any(my_any);
DynamicAny::DynStruct_var ds = DynamicAny::DynStruct::_narrow(da);
ds->seek(0);
da = ds->current_component();
DynamicAny::DynValue_var dv = DynamicAny::DynValue::_narrow(da);
CORBA::TypeCode_var tc = dv->type();
cout << tc->id() << endl;
-----------
Now some questions:
1. What is printed by the above C++ code? "IDL:A:1.0" or "IDL:B:1.0"?
2. If the typecode is for valuetype A, what happens to the members
defined in valuetype B? Seems they must be inaccessable yet still
recoverable if I convert the DynValue back to an any and extract the
value, because I can't truncate a B to an A.
3. If the typecode is for valuetype B, we now have the interesting case
where:
tc->equivalent(ds->type()->member_type(0))
is false. Is this going to confuse programmers or programs? I think it
will, since it means that if I try to insert dv into another DynStruct
via assign() or the like, it will fail, since the TypeCodes are no
longer equivalent.
4. Do the answers change if B is truncatable and the program can find
the TypeCode for B (perhaps via SendingContextRunTime)? How about if it
can't find the TypeCode?
What is a messaging router supposed to do if it receives multiple requests from a client with more than one type of QueueOrderingPolicy value? (Is this legal? Is it legal to have more than one QueueOrdering bit set in a single request?) How can it sort on priority, FIFO, and deadline simultaneously?
The spec doesn't make it clear what is a valid mix of policies and what is invalid. For example, should it be legal to set a RequestPriorityPolicy, MaxHopsPolicy or QueueOrderingPolicy value if the RoutingPolicy is ROUTE_NONE? Also, should setting both RequestEndTimePolicy and RelativeRequestTimeoutPolicy be illegal? Or must the client/server pick which ever one expires first?
It is impossible to use the routing protocol to communicate with servers that only support GIOP 1.0 or 1.1, because the information contained in struct MessageBody does not contain enough information to determine the alignment requirements of the contents of body member. The GIOP 1.0 & 1.1 RequestHeader struct contain an octet sequence for principle as the last member, and specify no alignment requirements for the message body. Thus, it is impossible for the final router to determine the proper alignment for the message body when marshalling a GIOP Request message for delivery to the target object. The same problem applies to the Response message.
What is the RSC when > using a PersistentPoller? Since it is a valuetype that can be passed > from one process to another, the RSC obviously can't be the same in the > other process as at the original invocation point. > > Anybody have any bright ideas for this one? Should it be empty? A copy > of the TSC at the poll point? Change MessageRouting:PersistentRequest > to have an attribute that provides access to a copy of the RSC, and > PersistentRequestRouter::create_persistent_request to have the RSC as an > "in" argument?
There is a sentence in the first paragraph of 22.6 that should be fixed: "The implementation of these methods must generate a method invocation as described in Section 22.14, Message Routing, on page 22-50." However, 22.2.5.3 allows asynchronous invocations to be delivered via synchronous protocols if the RoutingPolicy is ROUTE_NONE. This sentence should be changed to: "The implementation of these methods may generate a method invocation as described in Section 22.14, Message Routing, on page 22-50, depending on the effective RoutingPolicy for the invocation."
We recently ran into a problem with a foreign Vendor's ORB and it appears the spec is unclear on this issue. The problem occurs when a multi-threaded client is connecting to a server. The spec says (13.10.2.6): "Codeset negotiation is not performed on a per-request basis, but only when a client initially connects to a server. All text data communicated on a connection are encoded as defined by the TCSs selected when the connection is established." but is silent on what is supposed to happen if the client has multiple threads all trying to connect at the same time. The issue is that priority inversion can occur - either because the client sends out a request without the negotiated codeset before the one with the negotiated codeset, or because the server processes the request without the negotiated codeset before the one with the negotiated codeset (even if the latter was sent first). The problem we encountered was the latter. There are two possible approaches to solving this: a) Require the server to serialize connection establishment requests until the codeset (and other connection information) is negotiated. This requires that the client impose appropriate ordering on connection requests. b) Require that the client keep sending codeset (and other connection information) until it is sure that the server has received the information (by getting a reply back). This works ok unless you are exclusively using oneways. In this instance you have to keep sending codeset information forever (somewhat costly, and very costly for codebase information). CSIv2 (26.2.2.3) explicitly calls out (b) but I prefer (a). Do we have any guidance on what is supposed to happen?
There is a small issue with the restriction of where a valuetype chunk can end. The spec says "The data may be split into multiple chunks at arbitrary points except within primitive CDR types, arrays of primitive types, strings, and wstrings, or between the tag and offset of indirections. It is never necessary to end a chunk within one of these types as the length of these types is known before starting to marshal them so they can be added to the length of the currently open chunk." However, in the case of array of wchar, the length is not known before starting to marshal, since each char (in GIOP 1.2 and 1.3) is marshalled as a (sort-of) sequence of octets. I think it should be legal to end a valuetype chunk in the middle of an array of char.
21.3.9.2 states: "In the DSI model, since the parameters are first available when the user code calls arguments, receive_request is called from within arguments. It is possible that arguments is not called in the DSI model. The target may call set_exception before calling arguments. The ORB shall guarantee that receive_request is called once, either through arguments or through set_exception." The problem here, is that the DSI servant has already been invoked at this point, and the DSI implementation will be unaware that the server interceptor may have cancelled the invocation via raising a system exception or ForwardRequest user exception. So the DSI implementation will carry on, creating all sorts of wonderful havoc as it continues to interact with the ServerRequest PO. Any vendors want to comment on what their PI implementation does now? Proposed fix: First, we should define a new system exception minor code that the servant implementation can detect so that it can clean up and get out of the way as expeditiously as possible when raised by arguments or set_exception. Perhaps a minor code for OBJ_ADAPTER? Should there be two minor codes, to distinguish a system exception from ForwardRequest as the reason for cancelling the invocation? Second, we need some more text either in chapter 8 or 21 that states that any calls by the DSI implementation to ServerRequest::set_result or ServerRequest::set_exception will be ignored (or perhaps reraise the exception defined in the previous paragraph) if ServerRequestInterceptor::receive_request raises an exception.
The GIOP specification does not say anything at all about the rules for marshalling ValueBoxes. I believe the expected format is to marshal ValueBoxes as if they were a normal Value with a single member, and that they follow the normal rules about indirections and chunking. The spec should clearly state this.
ValueMembersSeq is not defined in the CORE Specification and appears in interface ORB, but I believe it is a typo of ValueMemberSeq: TypeCode create_value_tc ( in RepositoryId id, in Identifier name, in ValueModifier type_modifier, in TypeCode concrete_base, in ValueMembersSeq members );
Although I now think I know the intent of the spec, its is ambiguous if not plain wrong with respect to valuetype fragmentation. In particular 15.3.4.6: Bullet 1 says: "End tags, chunk size tags, and value tags are encoded using non-overlapping ranges so that the unmarshaling code can tell after reading each chunk whether: • another chunk follows (positive tag). • one or multiple value types are ending at a given point in the stream (negative tag). • a nested value follows (special large positive tag)." Bullet 3 says: "• For the purposes of chunking, values encoded as indirections or null are treated as non-value data." And the pseudo-BNF says: "(1) <value> ::= <value_tag> [ <codebase_URL> ] [ <type_info> ] <state> | <value_ref> (2) <value_ref> ::= <indirection_tag> <indirection> | <null_tag> (3) <value_tag> ::= long// 0x7fffff00 <= value_tag <= 0x7fffffff (4) <type_info> ::= <rep_ids> | <repository_id> (5) <state> ::= <octets> |<value_data>* [ <end_tag> ] (6) <value_data> ::= <value_chunk> | <value>" Now clearly the implication of bullet 1 is that an indirection or null must appear inside a chunk in a chunked encoding, otherwise you would be able to see the value 0 or -1 after a chunk and the -1 in particular could mean an end tag or an indirection. However the possible implication of bullet 3 and the BNF (note the use of "value data") is that nulls and indirections are values and thus must appear outside of chunks. Clearly the former interpretation is the correct one otherwise anarchy ensues. So I propose that we change the 3rd bullet to say: "For the purposes of chunking, values encoded as indirections or null are treated as if they were not values and therefore must always appear inside a chunk when a chunked encoding is in effect." and then change the BNF to say: "(1) <value> ::= <concrete_value> | <value_ref> (2) <concrete_value> ::= <value_tag> [ <codebase_URL> ] [ <type_info> ] <state> (3) <value_ref> ::= <indirection_tag> <indirection> | <null_tag> (4) <value_tag> ::= long// 0x7fffff00 <= value_tag <= 0x7fffffff (5) <type_info> ::= <rep_ids> | <repository_id> (6) <state> ::= <octets> |<value_data>* [ <end_tag> ] (7) <value_data> ::= <value_chunk> | <concrete_value>" etc
BTW I think the twiddle is incomplete because it is not reflected in the BNF for Identifier. I think it is better if the BNF always reflects the ultimate specification of a language's lexical definition. Otherwise compiler writers are apt to miss the subtleties. I'll propose some BNF changes if others agree
The CORBA 3.0 spec adds the following note in Section 4.5.1: ORB Initialization. "Whenever an ORB_init argument of the form -ORBxxx is specified, it is understood that the argument may be represented in different ways in different languages. For example, in Java -ORBxxx is equivalent to a property named org.omg.CORBA.ORBxxx." The approach stated in the above note does not work for -ORBInitRef. For example, if you have -ORBInitRef NameService=URL, you cannot translate the above arguments into a property named "org.omg.CORBA.ORBInitRef" because there can be only one property of this name and there may be many different services. This issue was slightly cover by Issue 3643 (java-rtf), which was not resolved. This issue becomes obvious and important because the note added in the CORBA 3.0 spec. Proposed solution: Arguments like "-ORBInitRef id=url" should be equivalent to a property named "org.omg.CORBA.ORBInitRef.id" with value "url".
For codesets in encapsulations we have: 15.3.3 - codesets must be "explicitly defined" Issue 4824 - "it is an error for a Service Context to depend on information that is not contained within the encapsulation to determine the codeset used within it" But in 13.8 there is no prescribed way of "explicitly defining" the codeset. Please, please can we simply define that the fallbacks in 13.10.2.6 apply everywhere that the codeset is not known (whether negotiated or not) and be done with it. Another alternative would be to add codeset parameters to the encode() and decode() functions of 13.8.
I believe that we send CSIv2 stuff in a GIOP Request until a corresponding GIOP reply has been containing corresponding CSIv2 context ids is sent. For Codeset, I think the policy is to send the service context in each GIOP request until a corresponding GIOP Reply is received, thereby saying that the "negotiation" is completed and excepted (otherwise an exception will be raised. We should probably look at the fact that multiple NSReq messages can be sent, and there are no corresponding reply messages depending on the service contexts. I think that these messages should be intercepted since they are delivering service contexts.
Here is a small proposal for GIOP 1.4 with Firewall and Bidirectional. We
would get rid of all the weird nasty service contexts and make it
simplistic. The FireWall messages are only allowed before any other GIOP
messages. BiDir messages can happen at any time according to their
protocol.
What do you think? Asside from some problems I see with BiDir
offer/challenge/response correlation, it is essentially equivalent to the
solution proposed in the adopted spec.
module GIOP {
enum MsgType_1_4{
Request, Reply, CancelRequest,
LocateRequest, LocateReply,
CloseConnection, MessageError,
Fragment, // GIOP 1.1 addition
// GIOP 1.4 additions
FirewallPathRequest, // 8
FirewallPathRepsonse, // 9
BiDirOffer, // 10
BiDirChallenge, // 11
BiDirResponse // 12
};
// Firewall Traversal GIOP 1.4
struct FirewallSpec {
boolean is_intelligent;
IOP::TaggedComponentSeq endpoints;
};
typedef sequence<FirewallSpec> FirewallPath;
struct FirewallPathRequestHeader {
unsigned long host_index;
FirewallPath path;
};
// No body follows.
enum FirewallPathResponseStatusType {
NO_EXCEPTION,
SYSTEM_EXCEPTION
};
struct FirewallPathResponseHeader{
FirewallPathResponseStatusType status;
boolean connection_complete;
};
// Marshalled body immediately follows
// Bidirectional GIOP 1.4
// To keep this file uncomplicated we can introduce the
// headers and put the marshalled bodies in a separate BiDir module
// Due due some issue about the challege/response protocol for this,
// there may be a need of an offer_id to correlate them.
struct BiDirOfferHeader{
unsigned long offer_id;
};
// Marshalled body immediately follows.
struct BiDirChallengeHeader {
unsigned long offer_id;
};
// Marshalled body immediately follows.
struct BiDirResponseHeader {
unsigned long offer_id;
};
// Marshalled body immediately follows.
};
Suppose you are sending a request (GIOP 1.2 or 1.3) and the request will be fragmented into two segments. The first segment is a Request message that has the GIOP Header and part of the Request Header. The second segment is a Fragment message that has a GIOP Header, a Fragment Header, and the body is the remainder of the Request Header and the Request Body. Section 15.4.2.2 of CORBA 3.0 states that the Request Body (in a Request Message) should always be aligned on an 8 octet boundary. My question is, in the above scenario, where the Request Body begins in the Fragment message, should the Request Body be aligned on an 8 octet boundary or not? I have not found anything in the specification that explicitly says what to do.
GIOP Conformance and Interceptor don't play well together. GIOP minor version conformance mandates two things. 1. That standard service contexts that are considered optional can be ignored should the implementation not understand them. 2. That certain service contexts get processed according to the specification of where they are defined. This requirement works well for GIOP 1.2 where a lot of them are optional, since (1) will apply. An implementation can claim 1.2 conformance and not process any of them. However, 1.3 and upcoming 1.4 will mandate the processing of them according to their specification. In many cases, this means that some default response may be required, which means that a GIOP 1.3, or later engine must have a "default" response for these service contexts. In an ORB that uses interceptors and has a generic GIOP messaging engine there is no way for the engine to "know" when or not to process a particular service context. It requires strict processing by the GIOP engine, or it requires "default" interceptors to be installed to maintain the level of conformance. However, interceptors have no way of "declaring" which service contexts they handle, and whether they they are overriding already installed (default) interceptors for processing those particular service contexts. For example, an non-transactional ORB that is GIOP 1.2 compliant must process the Transaction Service Context by raising a TRANSACTION_UNAVAILABLE exception, because by default the ORB is in the OTS_NOT_CONNECTED state. It cannot be ignored to comply with GIOP 1.2 (but by certain in implementations it ALWAYS is). A default interceptor is needed in the ORB implementation to do this. However, for an ORB configuration that wants to process this, there is no way for an interceptor to "override" default processing.
The spec appears silent as to whether valuetypes are allowed to support local interfaces. Table 3-10, for example, says nothing at all about local interfaces. There's a couple ways to look at this. First, valuetypes are not CORBA objects. Servants for local interfaces are direct CORBA object instances, i.e., the "local" declaration on an interface effectively removes the distinction between a CORBA object and its servant. If a valuetype were used as a servant for a local object, then the valuetype would itself also be a CORBA object. By this analysis, valuetypes should not be allowed to support local interfaces. Another way to look at it is that the valuetype should just inherit the local interface's operations and attributes without having any subtype/subclass relationship with the base local interface. This would be a rather pointless approach to take, is there would be no possibility of using the valuetype polymorphically with respect to the base local interface.
Inspired by a recent paper by Doug Schmidt and Steve Vinoski
and the resulting newsgroup discussion on comp.object.corba,
I have a feature request to introduce a better reflection
mechanism into CORBA.
At the moment, there is the CORBA::Object::get_interface()
operation to access a matching InterfaceDef entry in an
Interface Repository. Since an Interface Repository is
seldomly deployed, using this operation is pretty much
futile and will either return a nil reference or throw
an exception.
Therefore, I propose to add a new get_interface_def()
operation to the Object interface that returns a FullInter-
faceDef structure, as defined by the Interface Repository.
This structure contains all that a dynamic client (such as
the ones proposed by Schmidt&Vinoski, or software like
CorbaScript or Combat) needs to know about an interface.
A new _interface_def pseudo-operation then needs to be added
to GIOP. This could probably be done without a version change,
as no marshalling changes or new messages are involved, it's
just another operation.
On the server side, the IDL compiler would generate a suitable
implementation as part of the skeleton. This implementation
could just contain a binary representation of the FullInterface-
Description structure (just like a "precompiled" TypeCode) that
is dumped to the GIOP stream. (So that you don't need the
Interface Repository IDL around.)
Proposed resolution:
In chapter 4.3, "Object Reference Operations," add the following
operation to the Object interface:
module CORBA {
interface Object { // PIDL
... other operations ...
FullInterfaceDescription get_interface_def ();
};
};
Add the following explanation to 4.3.1, "Determining the Object
Interface"
4.3.1.2 get_interface_def
FullInterfaceDescription get_interface_def ();
The get_interface_def operation returns a data structure
describing the most derived type of the object addressed by
the reference. The FullInterfaceDescription structure includes
descriptions of all the operations and attributes in the
transitive closure of the inheritance graph of the interface
being described. See the Interface Repository chapter for the
contents of the data structure. Note that if an Interface
Repository is not available, object references contained in
this structure may be nil or inaccessible.
In chapter 15.4.2, "Request Message", update the text that
reads
In the case of CORBA::Object operations that are defined in
the CORBA Core (Section 4.2, "Object Reference Operations,"
on page 4-12) and that correspond to GIOP request messages,
the operation names are _interface, _is_a, _non_existent,
_domain_managers and _component.
to read
In the case of CORBA::Object operations that are defined in
the CORBA Core (Section 4.2, "Object Reference Operations,"
on page 4-12) and that correspond to GIOP request messages,
the operation names are _interface, _is_a, _non_existent,
_domain_managers, _component or _interface_def.
In the C++ language mapping, section 1.37.1, "Mapping of
PortableServer::Servant", add the following operation to
class ServantBase:
namespace PortableServer { // C++
class ServantBase {
... other operations ...
virtual CORBA::FullInterfaceDescription_ptr
_get_interface_def ();
};
}
Update the paragraph that reads,
ServantBase provides default implementations of the
_get_interface, _is_a and _non_existent object reference
operations [...]
to read
ServantBase provides default implementations of the
_get_interface, _is_a, _non_existent and _get_interface_def
object reference operations [...]
Add a new paragraph,
For static skeletons, the default implementation of the
_get_interface_def function returns information about the
interface associated with the skeleton class. For dynamic
skeletons, the default implementation uses the
_get_interface function to determine its return value.
Other language mappings might need similar updates.
By the way, since FullInterfaceDescription is only used as
a return value, only a pointer to FullInterfaceDescription
is needed. Therefore, you don't need the full Interface
Repository interface descriptions but only a pointer to an
incomplete type.
On the client side, you only need to pull in the Interface
Repository IDL if you are actually calling _get_interface_def.
On the server side, the skeleton can do some ORB-dependent
magic to push a precompiled binary data structure into the
result.
[..] It is used to indicate the relative amount of time for which a Request or its corresponding Reply may be delivered. After this amount of time, the Request is cancelled (if a response has not yet been received from the target) or the Reply is discarded (if the Request had already been delivered and a Reply returned from the target) [..] --------------------------------------------------------- Question: * What is the precise meaning of "Request is cancelled"? Does it mean that client ORB just gives up or does it mean that client tries, in kind of best effort semantics, to cancel request on server? If this cancellation fails, how will client user be informed about this? By a minor code in thrown Timeout exception? Is it possible to clarify this?
Fifth bullet near the beginning of this section states: Incarnations of a particular object may not overlap; that is, incarnate shall not be invoked with a particular ObjectId while, within the same POA, that ObjectId is in use as the ObjectId of an activated object or as the argument of a call to incarnate or etherealize that has not completed. Unfortunately, I do not see anywhere where the exception to be thrown from activate_object_with_id() for this case is specified. According to this text, if incarnate() is executing for a particular ObjectId, any calls to activate_object_with_id() should be rejected by the POA. This came up in comp.object.corba, where someone posted a question as to why Orbix 2000 throws the ObjectAlreadyActive exception for this case.
The CORBA specification has module SendingContext { //... interface CodeBase { //... CORBA::FullValueDescription meta(in CORBA::RepositoryId x); //... }; //... }; but there is no CORBA::FullValueDescription defined in the specification, yet the supplied <SendingContext.idl> file declares module SendingContext { //... interface CodeBase { //... CORBA::ValueDef::FullValueDescription meta(in CORBA::RepositoryId x); //... }; //... };
Related Specification: CommonObject Request Broker Architecture: Core Specification November 2002 Version 3.0 - Editorial edit to cover formal/02-11-03 Nature: Revision Subject: An extension of IOR to protect target objects Nature: Enhancement Issue Summary: IOR (Interoperable Object Reference) is the distributed reference of a CORBA object. The IOR of a target object is distributed to client applications that want to access the target object. Clients can easily connect to the target objects based on the location information in IOR. As a kind of object discovery scheme, IOR publishes some attributes related to target object, such as IP address, port number, internal object id, etc. As we know, many kinds of attacks can be performed to a target server when the IP address and port number of the target is exposed. The exposition of internal object id may also leads to security problems. We use Abstract IOR (AIOR) to make the originate IOR (we call it regular IOR) transparent to client applications, thus the target objects is protected from potential attacks. Proposed solution: We use proxy technology to protect target servers, following is the architecture of a typical scenario. Service Proxy (SP) acts as a portal for all background servers. SP will handle all requests from clients to background servers. So background servers are transparent to clients. +-------------+ +-------------+ | Client | Abstract IORs | Service | | application +-----------------++ Proxy | | | | | +-------------+ +---+--+--+---+ BS1's IORs | | | +---------------------------+ | | | BS2's IORs | | + +--------------+ | +------+-----+ + +-+ BS3's IORs | Background | +------+-----+ + | Server 1 | | Background | +------+-----+ +------------+ | Server 2 | | Background | +------------+ | Server 2 | +------------+ The core concept of the above architecture is Abstract IOR (AIOR). AIOR can be described by a simple equation: AIOR = SP's regular IOR + logical name Logical name is uniquely corresponding to an IOR of an object running on background server. So the SP should set up the mapping before corresponding request comes, and map the logical name in the AIOR to the regular IOR of the target object at background server for a coming request. The structure of AIOR is compatible to regular IOR. Firstly let's have a look at the structure of regular IOR defined at page 13-15. Then we will discuss how to support AIOR based on existing IOR data structures and what interfaces and methods will be defined. module IOP { // IDL // Standard Protocol Profile tag values typedef unsigned long ProfileId; struct TaggedProfile { ProfileId tag; sequence <octet> profile_data; }; typedef sequence <TaggedProfile> TaggedProfileSeq ; // an Interoperable Object Reference is a sequence of // object-specific protocol profiles, plus a type ID. struct IOR { string type_id; sequence <TaggedProfile> profiles; }; // Standard way of representing multicomponent profiles. // This would be encapsulated in a TaggedProfile. typedef unsigned long ComponentId; struct TaggedComponent { ComponentId tag; sequence <octet> component_data; }; typedef sequence<TaggedComponent> TaggedComponentSeq; }; CORBA specification defines 3 standard IOR profiles (at page 13-17): module IOP { const ProfileId TAG_INTERNET_IOP = 0; const ProfileId TAG_MULTIPLE_COMPONENTS = 1; const ProfileId TAG_SCCP_IOP = 2; typedef sequence <TaggedComponent> MultipleComponentProfile; }; The following are standard IOR components that can be included in TAG_INTERNET_IOP and TAG_MULTIPLE_COMPONENTS profiles, and may apply to IIOP, other GIOPs, ESIOPs, or other protocols. An ORB must not drop these components from an existing IOR (at page 13-19). module IOP { const ComponentId TAG_ORB_TYPE = 0; const ComponentId TAG_CODE_SETS = 1; const ComponentId TAG_POLICIES = 2; const ComponentId TAG_ALTERNATE_IIOP_ADDRESS = 3; const ComponentId TAG_ASSOCIATION_OPTIONS = 13; const ComponentId TAG_SEC_NAME = 14; const ComponentId TAG_SPKM_1_SEC_MECH = 15; const ComponentId TAG_SPKM_2_SEC_MECH = 16; const ComponentId TAG_KerberosV5_SEC_MECH = 17; const ComponentId TAG_CSI_ECMA_Secret_SEC_MECH = 18; const ComponentId TAG_CSI_ECMA_Hybrid_SEC_MECH = 19; const ComponentId TAG_SSL_SEC_TRANS = 20; const ComponentId TAG_CSI_ECMA_Public_SEC_MECH = 21; const ComponentId TAG_ GENERIC_SEC_MECH = 22; const ComponentId TAG_FIREWALL_TRANS = 23; const ComponentId TAG_SCCP_CONTACT_INFO = 24; const ComponentId TAG_JAVA_CODEBASE = 25; const ComponentId TAG_TRANSACTION_POLICY = 26; const ComponentId TAG_MESSAGE_ROUTERS = 30; const ComponentId TAG_OTS_POLICY = 31; const ComponentId TAG_INV_POLICY = 32; const ComponentId TAG_CSI_SEC_MECH_LIST = 33; const ComponentId TAG_NULL_TAG = 34; const ComponentId TAG_SECIOP_SEC_TRANS = 35; const ComponentId TAG_TLS_SEC_TRANS = 36; const ComponentId TAG_ACTIVITY_POLICY = 37; const ComponentId TAG_INET_SEC_TRANS = 123; }; The following additional components that can be used by other protocols are specified in the DCE ESIOP chapter of this document and CORBAServices, Security Service, in the Security Service for DCE ESIOP section (at page 13-19, 13-20): const ComponentId TAG_COMPLETE_OBJECT_KEY = 5; const ComponentId TAG_ENDPOINT_ID_POSITION = 6; const ComponentId TAG_LOCATION_POLICY = 12; const ComponentId TAG_DCE_STRING_BINDING = 100; const ComponentId TAG_DCE_BINDING_NAME = 101; const ComponentId TAG_DCE_NO_PIPES = 102; const ComponentId TAG_DCE_SEC_MECH = 103; // Security Service The following is the description of our proposed supplement to CORBA core specification. We add one component into module IOP: const ComponentId TAG_AIOR_LOGICALNAME = XXX; // XXX is an undetermined ComponentId. The TAG_AIOR_LOGICALNAME component has an associated value of type string encoded as a CDR encapsulation. We have not defined the interface of mapping logical names to regular IOR because now this function is local and its interoperability is not necessary. But if two or more SPs want to exchange their mapping items to provide more intelegent services, we may need to define the coresponding interfaces.
CORBA 3, chapter 13.8, defines the Codec interface to encode
arbitrary data values into CORBA::OctetSeq "blobs" and vice
versa. This interface can be used, e.g., to supply and retrieve
ServiceContext data using the PortableInterceptor interfaces.
In practice, the Codec interface is also being used for data
serialization, i.e., to store and retrieve arbitrary values in
files or other databases.
However, the interface is deficient in that it does not consider
all possible variables that are needed for interoperability.
It supports setting the CDR version that is to be used, but
neglects byteorder and codeset settings.
Consequently, the encoded values are platform-specific. If a
value was encoded on a little-endian system, it will not decode,
or worse, decode erroneously, on a big-endian system. The same
caveats apply to codesets, e.g., when an ISO-8859-1 encoded
blob is decoded using UTF-8 or Windows-1252.
To support interoperability, the Codec interface needs to be
extended.
My recommendation is to extend the CodecFactory interface,
so that it supports creating CDR version-, byteorder-, and
codeset-specific Codec instances, either supplying user-
provided values for each, or informing the user about chosen
defaults.
Example:
module IOP {
const EncodingFormat ENCODING_DEFAULT = -1;
typedef short ByteorderFormat;
const ByteorderFormat BYTEORDER_DEFAULT = -1;
const ByteorderFormat BYTEORDER_BIGENDIAN = 0;
const ByteorderFormat BYTEORDER_LITTLEENDIAN = 1;
struct EncodingExt {
EncodingFormat format;
octet major_version; // set to 0 for default
octet minor_version;
ByteorderFormat byteorder;
CONV_FRAME::CodeSetId char_data; // set to 0 for default
CONV_FRAME::CodeSetId wchar_data; // set to 0 for default
};
local interface CodecFactory {
// create_codec remains as before
Codec create_codec_ext (inout EncodingExt enc)
raises (UnknownEncoding);
};
};
The create_codec_ext operation would create an appropriate
Codec instance, if available; it will then set all "default"
members of the EncodingExt structure to their actual values,
so that the application can store this information along
with any encoded values.
One potential criticism of the above is that the encoding
format's parameters depend on the encoding format. For example,
there may be encoding formats that are byteorder-independent,
or that consistently use UTF-32 for strings, thus not needing
codeset parameters. Also, they may use wildly different
versioning. So a "better" solution might involve passing
the EncodingFormat, and an Any with a format-specific data
type.
That could look like:
module GIOP {
typedef short ByteorderFormat;
const ByteorderFormat BYTEORDER_DEFAULT = -1;
const ByteorderFormat BYTEORDER_BIGENDIAN = 0;
const ByteorderFormat BYTEORDER_LITTLEENDIAN = 1;
struct CDREncodingParameters {
octet major_version; // set to 0 for default
octet minor_version;
ByteorderFormat byteorder;
CONV_FRAME::CodeSetId char_data; // set to 0 for default
CONV_FRAME::CodeSetId wchar_data; // set to 0 for default
};
};
module IOP {
const EncodingFormat ENCODING_DEFAULT = -1;
local interface CodecFactory {
// create_codec remains as before
Codec create_codec_ext (inout EncodingFormat format,
inout Any parameters)
raises (UnknownEncoding);
};
};
Once we have consensus on the approach, I will gladly volunteer
to come up with a full set of editing instructionsA lot of the methods on the POA which have USE_DEFAULT_SERVANT or USE_SERVANT_MANAGER as policies don't describe in detail what should happen when one of these policies is set, but no default servant/servant manager is set. For example reference_to_servant, when USE_DEFAULT_SERVANT is set and default servant is registered we return the default servant, but what when no default servant is set, is then the ObjectNotActive the correct exception? Shouldn't this be something like a system exception (bad inv order, obj adapter or something like that?)
Made a typedef for the POA id new: local interface POA { typedef CORBA::OctetSeq POAid; } change: local interface POA { readonly attribute CORBA::OctetSeq id; } to: local interface POA { readonly attribute POAid id; }
Add a typedef for the POAManager id and use this throughout the spec for POAManager, POAManagerFactory and IORInterceptor add typedef string POAManagerId change in POAManager string get_id(); to POAManagerId get_id(); Or better (see other issue). readonly attribute POAManagerId the_id;
I would propose to change in the POAManager the following: State get_state(); string get_id(); to readonly attribute State the_state; readonly attribute string the_id; The get method just hide the fact that this are readonly attributes
The argument of the set_servant call has a small typo, it must be p_servant to match the full IDL spec some pages further
Given a property P defined by type B as PROP_NORMAL, two types T1 and T2 inherit from B but each strengthens the mode to PROP_READONLY and PROP_MANDATORY respectively. Then is there an implied strengthening to PROP_MANDATORY_READONLY in a further derived type T3 which inherits from both T1 and T2? Related to this, the OMG spec has nothing to say about waht exception should be raised by an attempted "weakening" of a property mode by a sub-type or exactly what is construed as a "weakening" with multiple inheritance. Another slightly different senario is: Given a property P defined by type B as PROP_READONLY, two types T1 and T2 inherit from B with one of them "strengthening" the mode of B to PROP_MANDATORY_READONLY. Is deriving a type T3 from both T1 and T2 legal?
The POA state inactive is not used consistent. On several places it is called deactivated instead of inactive. For example in 11.3.8.2, in the transient bullet, it mentions: "Once the POA's POAManager enters the dactivated state". Chapter 11.3.2.1 describes clearly the states are: active, inactive, holding and discarding. I would propose to scan the complete spec for these incorrect POA Manager state.
The grammar definition for valuetype <state_member> via the rule <declarators> includes <complex_declarator>. It should be clarified whether valuetype state members are intended to include <array_declarator>. IMHO clarification is needed as state members are usually mapped to accessor methods in programming languages. If permissible, the accessor methods would return a complex type.
The spec describes respository_id which should be repository_id. Is on two places, in 4.3.14 and 4.3
The overview of all system exceptions is missing several ones which seem to be availalble in http://www.omg.org/docs/omg/03-01-04 For example NO_IMPLEMENT_TABLE minor code 8 is missing
The "operation" field in the RequestHeader_1_2 struct is a string, which implies that it should be subject to code set conversion. However, existing practice seem to be that it is not converted, and there are other factors which could make it difficult for implementations to convert it. In addition, since the operation name is based on IDL/ASCII, conversion doesn't necessarily make sense. The easiest remedy would be to specify this as an exception in the text of the spec. The "correct" remedy would probably be to change the operation field from "string" to "sequence<octet>". This could cause problems at some point, but it might not break too much since the CDR encodings are the same.
In the CORBA specification, chapter 5 (Value Type Semantics), section 5.5 (Custom Marshalling), defines sequences of primitive types in the CORBA module, i.e., CORBA::StringSeq et al. Some of these types are then used by the DynamicAny and Portable Interceptor chapters. The presence of these typedefs in section 5.5 seems to imply that they only need to be defined if the ORB implements custom marshalling -- a feature still lacking in some open-source and commercial ORBs. In my experience, having worked with multiple ORBs, many of them do not provide the complete set of typedefs in their "orb.idl" file. Many ORBs only provide a limited set, usually, the set that is exercised by the other ORB features (such as PI). This implies that most ORBs added these typedefs on an "as needed" basis instead of simply referring to section 5.5. I suggest to move these typedefs from section 5.5 into chapter 4 (ORB interface), e.g., into section 4.2 (ORB operations) to highlight that these types should be present even if custom marshalling is not implemented by the ORB.