Distributed Object Systems
• What are they?– CORBA– DCOM– Java/RMI
• But what does it mean?– RPC for the object crowd– With all the tradeoffs/choices/distinctions of
RPC systems
Distributed Objects as RPC++
• Interface Description Language– Defines external view of objects
• Compilers / Precompilers– Language extensions
• Run Time System– Directory Services– Data Conversion– Security / Authentication
Distributed Object System:Distinctions
• Single language vs. multilingual– Cross-lingual?
• Platform independence– True cross-platform communication?
• “Extras”– Real-time features– Fault tolerance– Transaction support– …
The Big Three
• CORBA – DCE on steroids– Cross-lingual (primarily C++, Java)– Cross-platform– Many features
• DCOM – Microsoft’s answer– Some cross-lingual support (within Microsoft world)– Windows only– Built on DCE RPC and COM
• Java RMI– Single language, tightly integrated
CORBA: Background
• Object Management Group– Corporate-sponsored standards body– Members develop and vote on standards– Current specs include UML, CORBA
• Started April 1989• Working groups for extensible specifications
– RealTime CORBA– Fault-Tolerant CORBA– Embedded CORBA– Many more…
CORBA: Basics(Thanks to Doug Schmidt, Andrew Tannenbaum, and OMG for figures)
• Object Request Broker• Object Services
– Naming, “Trading” (property-based location), security, etc.• Common Facilities
– General interfaces, e.g., OpenDoc– Domain interfaces: Standards– Application interfaces: IDL specifications for a particular application
CORBA IDL
• Syntactic description of objects• Single Interface Definition Language
– Compiles to multiple binary interfaces:C, C++, Java, Smalltalk, Ada, COBOL, ?
• Assign Repository Identifier– Register interface in interface repository
• Generate Proxy– Client-side stub– Marshals invocation request– Unmarshals result
• Also Dynamic Invocation Interface– Invoke object when interface not known until runtime
Key ORB facilities
• Manipulate object references– Marshal/Unmarshal– Comparison
• Service Discovery– By name– By property– Interface repository and Implementation repository
• ORB/Proxy interface can be vendor specific
Invocation Models
• Default: Synchronous Semantics– Block for response– Exception on failure– At-most-once semantics
• One-Way Request– No response needed/possible– Non-blocking– Best effort semantics
• Deferred Synchronous– Caller can continue and later wait for result
Naming
• Object reference– Language independent “pointer”– POA: Adaptor to make server-side code accessible
to client
Message passing models
• Events– No guarantees– No persistence
• Notification– Events with filtering
Persistent Communications
• Callback model– Client provides object that
is called with result
• Polling Model– Client polls for results
• Messages Stored by ORB
Processes
• Client and Server distinct– Client processes are simple– Server potentially complex
• Agent processes– Interface to external agent system
Common Services
• Collection service– List/queue/etc. objects
• Iterator, get methods
– “Class library” for CORBA
• Query service– Construct collections searchable through declarative
query language
• Concurrency control service– Locking mechanisms
• Transaction service
Services – The Full List• CollectionGrouping objects into lists, queue, sets, etc.• Query Querying collections of objects in a declarative manner • Concurrency Allow concurrent access to shared objects • Transaction Flat and nested transactions on method calls over multiple
objects • Event Asynchronous communication through events • Notification Event-based asynchronous communication • Externalization Marshaling and unmarshaling of objects • Life cycle Creation, deletion, copying, and moving of objects • Licensing Attaching a license to an object • Naming Systemwide naming of objects • Property Associating (attribute, value) pairs with objects • Trading Publish and find the services an object has to offer • Persistence Persistently storing objects • Relationship Expressing relationships between objects • Security Secure channels, authorization, and auditing • Time Current time within specified error margins
Interoperability
• Multiple ORB vendors– Do you have to choose one?
• General Inter-ORB Protocol– Framework – without tranport– Internet Inter-ORB Protocol on TCP
• Message Types:– From client: Request, LocateRequest,
CancelRequest– From server: Reply, LocateReply– Both: CloseConnection, MessageError, Fragment
CORBA Programming
1. Select and install an Object Request Broker– More later – examples based on ORBIX, C++
2. Define the interfaces (IDL)
3. Create classes that implement interfaces
4. Write server function– Instantiates classes– Registers with ORB
5. Run Server
6. Write and Run Client
Ticket Office:IDL
// IDL – file ticket.idltypedef float Price;struct Place {
char row;unsigned long seat;
};Interface TicketOffice {
readonly attribute string namereadonly attribute unsigned long numberOfSeatsPrice getPrice (in Place chosenPlace);boolean bookSingleSeat (in Place chosenPlace, in string
creditCard);
};
Ticket Office:Compile IDL
% idl –B –S ticket.idl // Produces several files:• ticket.hh – C++ headers
#include <CORBA.h>Typedef CORBA::Float Price;Struct Place { CORBA::Char row; CORBA::ULong seat; };Class TicketOffice: public virtual CORBA::Object { public:
Virtual char* name() throw (CORBA::SystemException);…
Class TicketOfficeBOAImpl { … };
• ticketC.C // stubs for clients• ticketS.C // skeleton for server• TicketOffice_i.h, .C // Outline of implementation
TicketOffice:Implementation Declaration
class TicketOffice_i : public virtual TicketOfficeBOAImpl {char* m_name;Price m-highPrice; Price m-lowPrice;unsigned char** m_avail = {{1 1 1} {1 1 1} {1 1 1}};
public:TicketOffice_i (const char * theName, const Price theHighPrice, const
Price theLowPrice);virtual ~TicketOffice_i();virtual char* name() throw (CORBA::SystemException);virtual CORBA::ULong numberOfSeats()
throw (CORBA::SystemException);virtual Price getPrice (const Place& chosenPlace)
throw (CORBA::SystemException);virtual CORBA::Boolean bookSingleSeat (const Place& chosenPlace,
const char* creditCard) throw (CORBA::SystemException);};
TicketOffice:Implementation
#include “ticket_i.h”TicketOffice_i::TicketOffice_i (const char *
theName, const Price theHighPrice, const Price theLowPrice) :m_highPrice(theHighPrice), m_lowPrice (theLowPrice) {
m_name = new char[strlen(theName) + 1];strcpy(m_name, theName); }
TicketOffice_i::~TicketOffice_i() {delete[] m_name; }
char* TicketOffice_i::name() throw (CORBA::SystemException) {
return CORBA::string_dup(m_name); }
CORBA::ULong TicketOffice::numberOfSeats() throw (CORBA::SystemException) {
return 9; }
Price TicketOffice::getPrice (const Place& chosenPlace) throw (CORBA::SystemException) {
if (chosePlace.row == 1) return m_lowPrice;
else return m_high_price; }
CORBA::Boolean TicketOffice::bookSingleSeat (const Place& chosenPlace,const char* creditCard)throw (CORBA::SystemException) {
unsigned long rowIndex = chosenPlace.row – ‘A’;
if (m_avail[rowIndex][chosePlace.seat]) {m_avail[rowIndex][chosePlace.seat] = 0;return 1; }
else return 0; }
TicketOffice:Server
#include “ticket_i.h”int main() {
TicketOffice_i myTicketOffice(“Loeb”, 15.00, 10.00);
CORBA::Orbix.impl_is_read(“TicketOfficeSrv”);
}• Following registers server so it is
automatically started (or just run a.out)% putit TicketOfficeSrv a.out
TicketOffice:Client
#include “Ticket.hh”int main() {
TicketOffice_var toVar;tovar = TicketOffice::_bind(“:TicketOfficeSrv”);Place p = {‘B’, 1};if (toVar->bookSingleSeat(p, “1234 5678”))
cout << “Seat B1 booked at ” << toVar->name() <<“ for $” <<toVar->getPrice(p);
elsecout << “Seat B1 taken”;
}
More on Registering a Server
• Registration – generic (not Orbix-specific)CORBA::ORB_ptr orb =
“CORBA::ORB_init(argc, argv, “Orbix”);
CORBA::BOA_ptr boa = orb->BOA_init (argc, argv, “Orbix_BOA);
boa->impl_is_ready(“TicketOfficeSrv”);
• impl_is_ready defaults to waiting forever– impl_is_ready(name, ORBA::ULong timeOut);
// return if idle for timeOut
Wrapping Existing Code
• TIE approach– Creates object that interfaces CORBA to
identically declared existing C++ classes– Execute DEF_TIE macros to create/bind
• Multiple inheritance approach– CORBA interface implementation inherits
• BOAImpl• Legacy class
Finding operations:Simple Binding
• Simple
• Optionally specify host
• Can specify additional information: Marker– Server
myTicketOffice._marker(“Loeb”);myTicketOffice._bind(“TicketOffice”);
– Clientto_var p =to::_bind(“Loeb:TicketOffice”, “blitz”);
Finding Operations:Naming Service
• Database of bindings: name X object ref
• Naming context: Hierarchical structure
• A name is a sequence– typedef sequnce<NameComponent> Name;– Struct NameComponent
• id – real name• kind – application-specific information
Finding Operations:Naming Service
• NamingContext interface– Object resolve(in Name n) – get object given name
raises ( NotFound, CannotProceed, InvalidName );– Void bind(in Name n, in Object o) … -- bind object to name– Void bind_context(in Name n, in NamingContext nc) … – put
name in context
• CosNaming interface– Struct Binding { Name binding_name; {nobject, ncontext}
binding_type };– Typedef sequence<Binding> BindingList;– Interface NamingContext {
void list (in unsigned long how_many, out BindingList bl, out BindingIterator bi); };
Naming: Use
• Create hierarchy of naming contexts– E.g., tourism: theatre, hotel, …
• Bind specific name to context– tourism.theatre.loeb
• Resolution: Create name and resolve– name = new CosNaming::Name(3);– name->length(3);– name[0].id = CORBA::string_dup(“tourism”);– name[0].kind = CORBA::string_dup(“”);– name[1].id = …
• LoebTicketOffices = namecontext->resolve(name);– Also facilities to iterate over or select from multiple results
More on IDL
• IDL supports inheritance, multiple inheritance– Implementations must do the same– Can redefine operations at implementation level
• Can forward reference / recursive typesinterface a;
interface b { readonly attribute a a_inst };
interface a { … };
• #include, #define, etc. supported
Object References
• Can pass objects• Given class foo, get class foo_ptr (C++ pointer)
– Must manually maintain reference counts• foo_ptr p2 = p1; p2 = foo::_duplicate(p1);• CORBA::release(p2);
– Class foo_var: Automatically maintains reference counts
– Use _ptr for parameters• Passing objects: Server understands them
– Parameters defined in IDL– Server must have valid implementation (including
parameters) to invoke them
Casting
• Can assign object reference to object reference of parent class– Can’t use _var for target and _ptr for source
• Can Narrow: Assign object to child– child = child_class::_narrow(parent)
Dynamic Invocation(following syntax ORBIX-specific)
• Create an “on-the fly” referenceCORBA::Object_ptr target = // any objectCORBA::Request r(target, “operation”)r << CORBA::inMode << inparameter <<
CORBA::outMode << outparameter …;r.invoke();
• Can use repository to identify name/parameters to construct request
• Only way to make deferred synchronous calls– r.send_deferred(), r.poll_response(), r.get_response()– Also r.send_oneway()
Dynamic Skeleton Interface
• Server equivalent of DII– Not required to use DII
• Intended for gateways– Server doesn’t understand calls it can process– Trusts client/server to generate legal calls– Translates to legacy server protocol