
- •Advanced CORBA® Programming with C++
- •Review
- •Dedication
- •Preface
- •Prerequisites
- •Scope of this Book
- •Acknowledgments
- •Chapter 1. Introduction
- •1.1 Introduction
- •1.2 Organization of the Book
- •1.3 CORBA Version
- •1.4 Typographical Conventions
- •1.5 Source Code Examples
- •1.6 Vendor Dependencies
- •1.7 Contacting the Authors
- •Part I: Introduction to CORBA
- •Chapter 2. An Overview of CORBA
- •2.1 Introduction
- •2.2 The Object Management Group
- •2.3 Concepts and Terminology
- •2.4 CORBA Features
- •2.5 Request Invocation
- •2.6 General CORBA Application Development
- •2.7 Summary
- •Chapter 3. A Minimal CORBA Application
- •3.1 Chapter Overview
- •3.2 Writing and Compiling an IDL Definition
- •3.3 Writing and Compiling a Server
- •3.4 Writing and Compiling a Client
- •3.5 Running Client and Server
- •3.6 Summary
- •Part II: Core CORBA
- •Chapter 4. The OMG Interface Definition Language
- •4.1 Chapter Overview
- •4.2 Introduction
- •4.3 Compilation
- •4.4 Source Files
- •4.5 Lexical Rules
- •4.6 Basic IDL Types
- •4.7 User-Defined Types
- •4.8 Interfaces and Operations
- •4.9 User Exceptions
- •4.10 System Exceptions
- •4.11 System Exceptions or User Exceptions?
- •4.12 Oneway Operations
- •4.13 Contexts
- •4.14 Attributes
- •4.15 Modules
- •4.16 Forward Declarations
- •4.17 Inheritance
- •4.18 Names and Scoping
- •4.19 Repository Identifiers and pragma Directives
- •4.20 Standard Include Files
- •4.21 Recent IDL Extensions
- •4.22 Summary
- •Chapter 5. IDL for a Climate Control System
- •5.1 Chapter Overview
- •5.2 The Climate Control System
- •5.3 IDL for the Climate Control System
- •5.4 The Complete Specification
- •Chapter 6. Basic IDL-to-C++ Mapping
- •6.1 Chapter Overview
- •6.2 Introduction
- •6.3 Mapping for Identifiers
- •6.4 Mapping for Modules
- •6.5 The CORBA Module
- •6.6 Mapping for Basic Types
- •6.7 Mapping for Constants
- •6.8 Mapping for Enumerated Types
- •6.9 Variable-Length Types and _var Types
- •6.10 The String_var Wrapper Class
- •6.11 Mapping for Wide Strings
- •6.12 Mapping for Fixed-Point Types
- •6.13 Mapping for Structures
- •6.14 Mapping for Sequences
- •6.15 Mapping for Arrays
- •6.16 Mapping for Unions
- •6.17 Mapping for Recursive Structures and Unions
- •6.18 Mapping for Type Definitions
- •6.19 User-Defined Types and _var Classes
- •6.20 Summary
- •Chapter 7. Client-Side C++ Mapping
- •7.1 Chapter Overview
- •7.2 Introduction
- •7.3 Mapping for Interfaces
- •7.4 Object Reference Types
- •7.5 Life Cycle of Object References
- •7.6 Semantics of _ptr References
- •7.7 Pseudo-Objects
- •7.8 ORB Initialization
- •7.9 Initial References
- •7.10 Stringified References
- •7.11 The Object Pseudo-Interface
- •7.12 _var References
- •7.13 Mapping for Operations and Attributes
- •7.14 Parameter Passing Rules
- •7.15 Mapping for Exceptions
- •7.16 Mapping for Contexts
- •7.17 Summary
- •Chapter 8. Developing a Client for the Climate Control System
- •8.1 Chapter Overview
- •8.2 Introduction
- •8.3 Overall Client Structure
- •8.4 Included Files
- •8.5 Helper Functions
- •8.6 The main Program
- •8.7 The Complete Client Code
- •8.8 Summary
- •Chapter 9. Server-Side C++ Mapping
- •9.1 Chapter Overview
- •9.2 Introduction
- •9.3 Mapping for Interfaces
- •9.4 Servant Classes
- •9.5 Object Incarnation
- •9.6 Server main
- •9.7 Parameter Passing Rules
- •9.8 Raising Exceptions
- •9.9 Tie Classes
- •9.10 Summary
- •Chapter 10. Developing a Server for the Climate Control System
- •10.1 Chapter Overview
- •10.2 Introduction
- •10.3 The Instrument Control Protocol API
- •10.4 Designing the Thermometer Servant Class
- •10.5 Implementing the Thermometer Servant Class
- •10.6 Designing the Thermostat Servant Class
- •10.7 Implementing the Thermostat Servant Class
- •10.8 Designing the Controller Servant Class
- •10.9 Implementing the Controller Servant Class
- •10.10 Implementing the Server main Function
- •10.11 The Complete Server Code
- •10.12 Summary
- •Chapter 11. The Portable Object Adapter
- •11.1 Chapter Overview
- •11.2 Introduction
- •11.3 POA Fundamentals
- •11.4 POA Policies
- •11.5 POA Creation
- •11.6 Servant IDL Type
- •11.7 Object Creation and Activation
- •11.8 Reference, ObjectId, and Servant
- •11.9 Object Deactivation
- •11.10 Request Flow Control
- •11.11 ORB Event Handling
- •11.12 POA Activation
- •11.13 POA Destruction
- •11.14 Applying POA Policies
- •11.15 Summary
- •Chapter 12. Object Life Cycle
- •12.1 Chapter Overview
- •12.2 Introduction
- •12.3 Object Factories
- •12.4 Destroying, Copying, and Moving Objects
- •12.5 A Critique of the Life Cycle Service
- •12.6 The Evictor Pattern
- •12.7 Garbage Collection of Servants
- •12.8 Garbage Collection of CORBA Objects
- •12.9 Summary
- •Part III: CORBA Mechanisms
- •Chapter 13. GIOP, IIOP, and IORs
- •13.1 Chapter Overview
- •13.2 An Overview of GIOP
- •13.3 Common Data Representation
- •13.4 GIOP Message Formats
- •13.5 GIOP Connection Management
- •13.6 Detecting Disorderly Shutdown
- •13.7 An Overview of IIOP
- •13.8 Structure of an IOR
- •13.9 Bidirectional IIOP
- •13.10 Summary
- •14.1 Chapter Overview
- •14.2 Binding Modes
- •14.3 Direct Binding
- •14.4 Indirect Binding via an Implementation Repository
- •14.5 Migration, Reliability, Performance, and Scalability
- •14.6 Activation Modes
- •14.7 Race Conditions
- •14.8 Security Considerations
- •14.9 Summary
- •Part VI: Dynamic CORBA
- •Chapter 15 C++ Mapping for Type any
- •15.1 Chapter Overview
- •15.2 Introduction
- •15.3 Type any C++ Mapping
- •15.4 Pitfalls in Type Definitions
- •15.5 Summary
- •Chapter 16. Type Codes
- •16.1 Chapter Overview
- •16.2 Introduction
- •16.3 The TypeCode Pseudo-Object
- •16.4 C++ Mapping for the TypeCode Pseudo-Object
- •16.5 Type Code Comparisons
- •16.6 Type Code Constants
- •16.7 Type Code Comparison for Type any
- •16.8 Creating Type Codes Dynamically
- •16.9 Summary
- •Chapter 17. Type DynAny
- •17.1 Chapter Overview
- •17.2 Introduction
- •17.3 The DynAny Interface
- •17.4 C++ Mapping for DynAny
- •17.5 Using DynAny for Generic Display
- •17.6 Obtaining Type Information
- •17.7 Summary
- •Part V: CORBAservices
- •Chapter 18. The OMG Naming Service
- •18.1 Chapter Overview
- •18.2 Introduction
- •18.3 Basic Concepts
- •18.4 Structure of the Naming Service IDL
- •18.5 Semantics of Names
- •18.6 Naming Context IDL
- •18.7 Iterators
- •18.8 Pitfalls in the Naming Service
- •18.9 The Names Library
- •18.10 Naming Service Tools
- •18.11 What to Advertise
- •18.12 When to Advertise
- •18.13 Federated Naming
- •18.14 Adding Naming to the Climate Control System
- •18.15 Summary
- •Chapter 19. The OMG Trading Service
- •19.1 Chapter Overview
- •19.2 Introduction
- •19.3 Trading Concepts and Terminology
- •19.4 IDL Overview
- •19.5 The Service Type Repository
- •19.6 The Trader Interfaces
- •19.7 Exporting Service Offers
- •19.8 Withdrawing Service Offers
- •19.9 Modifying Service Offers
- •19.10 The Trader Constraint Language
- •19.11 Importing Service Offers
- •19.12 Bulk Withdrawal
- •19.13 The Admin Interface
- •19.14 Inspecting Service Offers
- •19.15 Exporting Dynamic Properties
- •19.16 Trader Federation
- •19.17 Trader Tools
- •19.18 Architectural Considerations
- •19.19 What to Advertise
- •19.20 Avoiding Duplicate Service Offers
- •19.21 Adding Trading to the Climate Control System
- •19.22 Summary
- •Chapter 20. The OMG Event Service
- •20.1 Chapter Overview
- •20.2 Introduction
- •20.3 Distributed Callbacks
- •20.4 Event Service Basics
- •20.5 Event Service Interfaces
- •20.6 Implementing Consumers and Suppliers
- •20.7 Choosing an Event Model
- •20.8 Event Service Limitations
- •20.9 Summary
- •Part VI: Power CORBA
- •Chapter 21. Multithreaded Applications
- •21.1 Chapter Overview
- •21.2 Introduction
- •21.3 Motivation for Multithreaded Programs
- •21.4 Fundamentals of Multithreaded Servers
- •21.5 Multithreading Strategies
- •21.6 Implementing a Multithreaded Server
- •21.7 Servant Activators and the Evictor Pattern
- •21.8 Summary
- •22.1 Chapter Overview
- •22.2 Introduction
- •22.3 Reducing Messaging Overhead
- •22.4 Optimizing Server Implementations
- •22.5 Federating Services
- •22.6 Improving Physical Design
- •22.7 Summary
- •Appendix A. Source Code for the ICP Simulator
- •Appendix B. CORBA Resources
- •Bibliography

IT-SC book: Advanced CORBA® Programming with C++
A structure of type ProfileBody_1_1 applies only to IIOP and encodes how a client can locate the target object of a request. If a server uses IIOP as its transport, object references created by that server contain an IIOP profile body. To establish a connection, the client side decodes that profile body and uses the host and port number to establish a connection to the server. Having established a connection, the client sends the object key with every request. In other words, the host and port identify the target server, and the object key is decoded by the server to determine which specific object should receive the request.
13.8 Structure of an IOR
CORBA uses interoperable object references as the universal means of identifying an object. As mentioned in Section 2.5.1, object references are opaque to the client-side application code and completely encapsulate everything that is necessary to send requests, including the transport and protocol to be used.
IIOP is the main interoperable protocol used by CORBA, and every ORB claiming interoperability must support IIOP. CORBA also specifies another protocol, known as the DCE Common Inter-ORB Protocol (DCE-CIOP). This protocol is optional (interoperable ORBs need not support it) and uses DCE-RPC as its underlying transport.
DCE-CIOP is an example of what is known as an environment-specific inter-ORB protocol (ESIOP). Environment-specific protocols permit use of CORBA over transports and protocols other than TCP/IP and permit vendors to support proprietary protocols that are optimized for particular environments. As CORBA evolves, we will see support for other transports and protocols. For example, it is likely that a future version will support connection-oriented GIOP over ATM networks and also allow use of connectionless transports such as UDP.
This means that object references must be extensible so that future protocols can be added without breaking existing clients and servers. CORBA specifies an encoding for IORs that meets this requirement. Not only can IORs be extended to carry protocol information for future protocols, but also it is possible for vendors to add their own proprietary protocols. In addition, a single IOR can contain information for multiple protocols. For example, an IOR can contain both IIOP and DCE-CIOP information simultaneously. In that way, clients that are limited to DCE-CIOP can use the same IOR to communicate with an object that clients that are limited to IIOP can use. If a client has access to both transports simultaneously, the ORB run time dynamically chooses which transport to use for a request.
An IOR can also contain multiple profile bodies for the same protocol. For example, an IOR could contain three IIOP profiles, each indicating a different host and port number. When a client invokes a request via the IOR, the ORB run time dynamically chooses one of the three server endpoints indicated in the IOR. This provides a hook for load balancing as well as fault-tolerant ORBs that replicate the same single CORBA object in multiple server processes.[8]
545

IT-SC book: Advanced CORBA® Programming with C++
[8] The OMG has taken the first steps to standardize fault tolerance (see [22]).
The CORBA specification uses pseudo-IDL to define how an IOR encodes the information required to send a request to the correct target object:
module IOP { |
// PIDL |
typedef unsigned long ProfileId; |
|
const ProfileId |
TAG_INTERNET_IOP = 0; |
const ProfileId |
TAG_MULTIPLE_COMPONENTS = 1; |
struct TaggedProfile { |
|
ProfileId |
tag; |
sequence<octet> profile_data; |
|
}; |
|
struct IOR { |
type_id; |
string |
|
sequence<TaggedProfile> profiles; |
|
}; |
|
typedef unsigned long ComponentId; struct TaggedComponent {
ComponentId tag; sequence<octet> component_data;
};
typedef sequence<TaggedComponent> MultipleComponentProfile;
};
At first glance, this is intimidating, but things are not quite as bad as they look. The main data type in this IDL is struct IOR, which defines the basic encoding of an IOR as a string followed by a sequence of profiles. The type_id string provides the interface type of the IOR in the repository ID format we discuss in Section 4.19. The profiles field is a sequence of protocol-specific profiles, usually one for each protocol supported by the target object. For example, an IOR for an object that can be reached either via IIOP or via DCE-CIOP has two elements in the profiles sequence. Figure 13.7 shows the main structure of an IOR.
Figure 13.7 Main structure of an IOR.
To illustrate, an IOR for the controller in our climate control system contains a repository ID with value IDL:CCS/Controller:1.0. Assuming that the ORB used to implement the controller object supports only IIOP, the repository ID is followed by a single profile containing a structure of type TaggedProfile. A tagged profile contains a tag field and an octet sequence that contains the profile body identified by the tag. In the case of IIOP 1.1, the tag is TAG_INTERNET_IOP (zero), and the profile_data
member encodes a structure of type IIOP::ProfileBody as shown in Section 13.7.
546

IT-SC book: Advanced CORBA® Programming with C++
The OMG administers the namespace for tag values. To support a proprietary protocol, a vendor can request assignment of one or more tag values for its exclusive use. The tag value determines the format of the profile data, so vendors can use an exclusive tag to indicate a vendor-specific profile that encodes the addressing information for a proprietary protocol. Clients attempt to decode the profile information only for those tags they know about and ignore all other profiles. In that way, proprietary protocol information inside an IOR does not compromise interoperability. As long as the IOR contains at least one IIOP profile, any interoperable ORB can use the IOR.
If an IOR profile has the tag TAG_MULTIPLE_COMPONENTS, the profile_data field contains a sequence of type MultipleComponentProfile. Multiple component profiles themselves have internal structure, which is encoded as a sequence of structures of type TaggedComponent. As for profile tags, the OMG also administers the namespace for component tags, so vendors can encode proprietary information in an IOR without compromising interoperability.
Multicomponent profiles are used for service-specific information. For example, ORBs that support the OMG Security Service add a component to every IOR that describes which security mechanism is to be used to secure a request. Another component is used to describe which codeset is to be used for requests containing wide characters.
One of the components specified by CORBA encodes the ORB type. The ORB type describes the specific ORB vendor and ORB version that was used to create the IOR (not all ORBs use this component). The ORB type component enables a number of optimizations. Specifically, if an IOR contains the ORB type, a client can determine whether the IOR was created by the same ORB as the one used by the client. If it was, the client knows how to decode the proprietary parts of the IOR because the IOR was created by the same ORB. The proprietary part of the IOR in turn can contain information to optimize communication between client and server (we show some of these optimizations in Section 14.4.6).
13.9 Bidirectional IIOP
As mentioned in Section 13.4, CORBA 2.3 added GIOP 1.2 and IIOP 1.2 to enable bidirectional communication. This allows client and server to reverse roles without the need to open a separate connection that may be blocked by a firewall. At the time of writing, the specification is undergoing changes, and implementations are unlikely to appear before mid-1999, so we do not cover version 1.2 in detail in this chapter. Here is a summary of the major changes.
GIOP 1.2 does not add new message types but adds extensions to most of the message headers and bodies. These extensions support the additional information that must be exchanged for bidirectional communication.
GIOP 1.2 adds a LOCATE_FORWARD_PERM reply status, which is intended to ease object migration (see Section 14.5).
547

IT-SC book: Advanced CORBA® Programming with C++
GIOP 1.2 tightens the alignment restrictions for a request body to make remarshaling after a LOCATE_FORWARD reply more efficient.
IIOP 1.2 adds additional information to the service context to support bidirectional communication. It also defines a policy that enables bidirectional communication only if both client and server agree to use it. This policy allows administrators to disable bidirectional communication over insecure links and thereby prevent clients from masquerading as someone else's call-back object. If bidirectional communication is disabled, GIOP 1.2 uses a separate connection for callbacks.
13.10 Summary
GIOP specifies the on-the-wire representation of data and the messages that are exchanged between clients and servers. IIOP adds the specific information required for ORBs to interoperate via TCP/IP. All interoperable ORBs support IIOP. In addition, ORBs may support DCE-CIOP or proprietary protocols.
IORs contain the interface type of an object and one or more protocol profiles. Each profile contains the information required by a client to send a request using a specific protocol. A single IOR can contain addressing information for several protocols simultaneously. This arrangement allows a single CORBA object to be reached via different transports and also provides a basic protocol hook for fault-tolerant ORBs.
An IIOP 1.1 profile can contain a number of tagged components. Components encode additional information; for example, they can identify the codeset or security mechanism to be used for a request. Vendors can add proprietary components to IORs to support value-added features or optimizations.
CORBA defines a particular component that identifies the ORB vendor and ORB version. If this component is present in an IOR, clients can detect whether both client and server use the same ORB. If they do, clients can take advantage of this knowledge to optimize communication with the server.
GIOP 1.2 and IIOP 1.2 permit clients and servers to communicate across firewalls over a single connection.
548