Introduzione
Nell’era
di Internet e delle grandi Intranet aziendali, il modello computazionale
dominante è chiaramente quello distribuito. Un tipico ambiente distribuito
vede la presenza di mainframe, server Unix e macchine Windows e pone quindi
seri problemi di interoperabilità tra piattaforme differenti, sistemi
operativi differenti e linguaggi differenti.
Lo
scopo dichiarato delle specifiche CORBA è proprio quello di definire
un’infrastruttura standard per la comunicazione tra e con oggetti remoti
ovunque distribuiti, indipendentemente dal linguaggio usato per implementarli
e dalla piattaforma di esecuzione. E’ bene quindi notare che a differenza
di altre tecnologie distribuite quali RMI, Servlet o EJB, non si sta parlando
di una tecnologia legata ad una specifica piattaforma, ma di uno standard
indipendente dal linguaggio adottato che consente ad oggetti Java di comunicare
con “oggetti” sviluppati in COBOL, C++ o altri linguaggi ancora.
CORBA
significa Common Object Request Broker Architecture e non rappresenta uno
specifico prodotto, bensì un’insieme di specifiche volte a definire
un’architettura completa e standardizzata di cui esistono varie implementazioni.
Le specifiche sono prodotte da OMG, un consorzio che comprende più
di 800 aziende e che include i più illustri marchi dell’industria
informatica.
L’elemento
fondamentale dell’intera architettura è il canale di comunicazione
degli oggetti nell’ambiente distribuito, l’Object Request Broker (ORB).
Le
specifiche CORBA 1.1 sono state pubblicate da OMG nell’autunno del 1991
e definivano un’API ed un linguaggio descrittivo per la definizione delle
interfacce degli oggetti CORBA, Interface Definition Language (IDL). Soltanto
nel Dicembre del 1994 con CORBA 2.0 vennero definiti i dettagli sulla comunicazione
tra differenti implementazioni di ORB con l’introduzione dei protocolli
GIOP ed IIOP.
Sebbene
CORBA possa essere utilizzato con la maggior parte dei linguaggi di programmazione,
Java risulta il linguaggio privilegiato per implementare le sue specifiche
in un ambiente eterogeneo in quanto permette agli oggetti CORBA di essere
eseguiti indifferentemente su mainframe, network computer o telefono cellulare...
Nello
sviluppo di applicazioni distribuite Java e CORBA si completano a vicenda:
CORBA affronta e risolve il problema della trasparenza della rete, Java
quello della trasparenza dell’implementazione rispetto alla piattaforma
di esecuzione.
Object Management
Group
L’OMG
è un consorzio no-profit interamente dedicato alla produzione di
specifiche e di standard; vede la partecipazione sia di grandi colossi
dell’informatica sia di compagnie medio/piccole.
L’attività
di OMG cominciò nel 1989 con soli 8 membri tra cui Sun Microsystems,
Philips, Hewlett-Packard e 3Com. Le specifiche più conosciute prodotte
dal consorzio sono sicuramente UML e CORBA che comunque, nella logica OMG,
rappresentano strumenti strettamente cooperanti nella realizzazione di
applicazioni Enterprise OO.
Lo
scopo di OMG è principalmente quello di produrre e mantenere una
suite di specifiche di supporto per lo sviluppo di software distribuito,
coprendo l’intero ciclo di vita di un progetto: analisi, design, sviluppo,
run-time e manutenzione.
Con
lo scopo di ridurre complessità e costi di realizzazione di nuove
applicazioni distribuite, il consorzio ha definito un framework: Object
Management Architecture (OMA). OMA è il centro di tutte le attività
del consorzio, al suo convivono tutte le tecnologie OMG. Nell’ottica OMG
la definizione di un framework prescinde dall’implementazione e si “limita”
alla definizione dettagliata delle interfacce di tutti i componenti individuati.
I componenti
OMA sono:
-
Object
Request Broker (ORB): è l’elemento fondamentale dell’architettura.
E’ il canale che fornisce l’infrastruttura che permette agli oggetti di
comunicare indipendentemente dal linguaggio e dalla piattaforma adottata.
La comunicazione tra tutti i componenti OMA è sempre mediata e gestita
dall’ORB.
-
Object
Services: standardizzano la gestione e la manutenzione del ciclo di vita
degli oggetti. Sono fornite le interfacce base per la creazione e l’accesso
agli oggetti. Sono indipendenti dal singolo dominio applicativo e possono
essere usati da più applicazioni distribuite (Es. Naming e Trading
Service).
-
Common
Facilities: comunemente conosciute come CORBAFacilities. Forniscono due
tipologie di servizi, orizzontali e verticali. Quelli orizzontali sono
funzionalità applicative comuni: gestione stampe, gestione documenti,
database e posta elettronica. Quelli verticali sono invece destinati ad
una precisa tipologia di applicazioni (Es. telecomunicazioni).
-
Domain
Interfaces: possono combinare common facilities ed object services. Forniscono
funzionalità altamente specializzate per ristretti domini applicativi.
-
Application
Objects: è l’insieme di tutti gli altri oggetti sviluppati per una
specifica applicazione. Sono gli oggetti applicativi. Non è un’area
di standardizzazione OMG.
Di
questi componenti OMG fornisce una definizione formale definendone sia
le interfacce (mediante IDL), sia la semantica. La definizione mediante
interfacce lascia ampio spazio al mercato di componenti software di agire
sotto le specifiche con differenti implementazioni e consente la massima
interoperabilità tra componenti di vendor differenti.
I servizi CORBA
I
CORBAservices sono una collezione di servizi system-level descritti dettagliatamente
con un’interfaccia IDL, sono destinati a completare ed estendere le funzionalità
fornite dall’ORB. Forniscono un supporto che va a coprire lo spettro completo
delle esigenze di una qualunque applicazione distribuita.
Alcuni
dei servizi standardizzati da OMG (ad esempio il Naming Service), sono
diventati fondamentali nella programmazione CORBA e sono presenti in tutte
le implementazioni. Altri servizi appaiono invece meno interessanti nella
pratica comune, assumono un significato solo dinanzi ad esigenze particolari
e non sono presenti nella maggior parte delle implementazioni sul mercato.
OMG
ha pubblicato le specifiche di ben 15 servizi:
-
Collection
Service: fornisce meccanismi di creazione ed utilizzo per le più
comuni tipologie di collection.
-
Concurrency
Control Service: definisce un lock manager che fornisce meccanismi di gestione
dei problemi di concorrenza nell’accesso ad oggetti agganciati all’ORB.
-
Event
Service: fornisce un event channel che consente ai componenti interessati
ad uno specifico evento, di ricevere una notifica pur non conoscendo nulla
del componente generatore.
-
Externalization
Service: definisce meccanismi di streaming per il trattamento di dati da
e verso i componenti.
-
Licensing
Service: fornisce meccanismi di controllo e verifica dell’utilizzo di un
componente. Pensato per l’implementazione di politiche “pago per quel che
uso”.
-
Lyfe Cycle
Service: definisce le operazioni necessarie a gestire il ciclo di vita
di un componente sull’ORB (creare, copiare e rimuovere).
-
Naming
Service: consente ad un componente di localizzare risorse (componenti o
altro) mediante nome. Permette di interrogare sistemi di directory e naming
già esistenti (NIS, NDS, X.500, DCE, LDAP). E’ il servizio più
utilizzato.
-
Persistence
Service: fornisce mediante un’unica interfaccia le funzionalità
necessarie alla memorizzazione di un componente su più tipologie
di server (ODBMS, RDBMS e file system).
-
Properties
Service: permette la definizione di proprietà legate allo stato
di un componente
-
Query
Service: fornisce meccanismi di interrogazione basati su un’estensione
di SQL chiamata Object Query Language.
-
Relationship
Service: permette di definire e verificare in modo dinamico varie tipologie
di associazioni e relazioni tra componenti (associazioni dinamiche e contenimento).
-
Security
Service: è un framework per la definizione e la gestione della sicurezza
in ambiente distribuito. Copre ogni possibile aspetto: autenticazione,
definizione di credenziali e gestione per delega, definizione di access
control list e non-repudiation.
-
Time Service:
definisce un’interfaccia di sincronizzazione tra componenti in ambiente
distribuito.
-
Trader
Service: fornisce un meccanismo modello “Yellow Pages” per i componenti.
-
Transaction
Service: fornisce un meccanismo di two-phase commit sugli oggetti agganciati
all’ORB che supportano il rollback, definisce transazioni flat o innestate.
Le basi CORBA
CORBA
ed OMA in genere si fondano su alcuni fondamentali principi di design:
-
Separazione
tra interfaccia ed implementazione: un client è legato all’interfaccia
di un oggetto CORBA, non alla sua implementazione
-
Location
transparency ed access transparency: l’utilizzo di un qualunque oggetto
CORBA non presuppone alcuna conoscenza sulla sua effettiva localizzazione
-
Typed
interfaces: ogni riferimento ad un oggetto CORBA ha un tipo definito dalla
sua interfaccia
Parlando
di CORBA, è particolarmente significativo il concetto di trasparenza,
inteso sia come location transparency, sia come trasparenza del linguaggio
di programmazione adottato. In pratica è trasparente al client la
collocazione locale o remota di un oggetto. La location transparency è
garantita dalla mediazione dell’ORB.
Architettura CORBA
L’architettura
CORBA ruota intorno al concetto di Objects Request Broker. L’ORB è
il servizio che gestisce la comunicazione in uno scenario distribuito agendo
da intermediario tra gli oggetti remoti: individua l’oggetto sulla rete,
comunica la richiesta all’oggetto, attende il risultato e lo comunica indietro
al client.
|
Figura
1 — Architettura CORBA
Come
detto in precedenza, l’ORB opera in modo tale da nascondere al client tutti
i dettagli sulla localizzazione degli oggetti sulla rete e sul loro linguaggio
d’implementazione; è quindi l’ORB ad individuare l’oggetto sulla
rete e ad effettuare le opportune traslazioni nel linguaggio d’implementazione.
Queste traslazioni sono possibili solo per quei linguaggi per cui è
stato definito un mapping verso IDL (questa definizione è stata
operata per i linguaggi più comuni).
In
figura 1 si può osservare l’architettura CORBA nel suo complesso:
-
Object:
è l’entità composta da identity, interface ed implementation
(Servant nel gergo CORBA).
-
Servant:
è l’implementazione dell’oggetto remoto. Definisce i metodi specificati
dall’interfaccia in un linguaggio di programmazione.
-
Client:
è l’entità che invoca i metodi (operation nel gergo CORBA)
del Servant. L’infrastruttura dell’ORB opera in modo tale da rendergli
trasparenti i dettagli sulla comunicazione remota.
-
ORB: l’ORB
è l’entità logica che fornisce i meccanismi per comunicare,
in modo trasparente, le richieste da un client all’oggetto remoto. Le chiamate
del client sono assimilabili a semplici invocazioni locali, questo grazie
all’operato dell’ORB che svincola completamente il client dai dettagli
di comunicazione.
-
ORB Interface:
essendo un’entità logica, l’ORB può essere implementato in
molti modi. Le specifiche CORBA definiscono l’ORB mediante un’interfaccia
astratta, nascondendo completamente alle applicazioni i dettagli d’implementazione.
-
IDL stub
e skeleton: lo stub opera da collante tra client ed ORB; lo skeleton ha
la stessa funzione per il server. Stub e skeleton sono generati nel linguaggio
adottato da un compilatore apposito che opera partendo da una definizione
IDL.
-
Dynamic
Invocation Interface (DII): è l’interfaccia che consente ad un client
di inviare dinamicamente una request ad un oggetto remoto senza conoscerne
la definizione dell’interfaccia e senza avere un legame con lo stub. Consente
inoltre ad un client di effettuare due tipi di chiamate asincrone: deferred
synchronous (separa le operazioni di send e di receive) e oneway (solo
send).
-
Dynamic
Skeleton Interface (DSI): è l’analogo lato server del DII. Consente
ad un ORB di recapitare una request ad un oggetto che non ha uno skeleton
statico, per cui cioè non è stato definito precisamente il
tipo a tempo di compilazione. Il suo utilizzo è totalmente trasparente
per un client.
-
Object
Adapter: assiste l’ORB nel recapitare le request ad un’implementazione
valida e nelle operazioni di attivazione/disattivazione degli oggetti.
Il suo compito principale è quello di legare l’implementazione di
un oggetto all’ORB.
Invocazione CORBA
Utilizzando
l’ORB, un client, può inviare una Request in modo trasparente ad
un oggetto CORBA che risieda sulla stessa macchina o ovunque sulla rete.
Per raggiungere questo livello di astrazione, ogni oggetto remoto è
dotato di uno stub e di uno skeleton; questi due elementi agiscono rispettivamente
da collante tra client ed ORB e tra ORB ed oggetto CORBA.
In
maniera similare a quanto accade in RMI, lo stub effettua il marshalling
dei dati, traslando i data types dal linguaggio di programmazione client-side
ad un generico formato CORBA; quest’ultimo è convogliato via rete
dal messaggio di Request.
Il
client quindi invoca i metodi non sull’oggetto remoto, bensì sul
suo stub locale. L’effettiva invocazione remota viene operata dallo stub.
Come si vedrà più dettagliatamente in uno dei prossimi articoli,
il meccanismo dello stub è una precisa implementazione del pattern
Proxy.
In
maniera speculare allo stub, l’unmarshalling dei dati è eseguito
sul server dallo skeleton. In questo caso il formato della Request viene
traslato nel linguaggio di programmazione server-side.
|
Figura
2 — Una richiesta da client ad oggetto CORBA
Stub
e skeleton vengono generati automaticamente da un compilatore a partire
dalla definizione IDL dell’oggetto CORBA
Interoperabilità
tra ORB
Le
specifiche CORBA 1.1 si limitavano a dare le basi per la portabilità
di oggetti applicativi e non garantivano affatto l’interoperabilità
tra differenti implementazioni di ORB. Le specifiche 2.0 colmarono questa
significativa lacuna con la definizione di un protocollo (GIOP), espressamente
pensato per interazioni ORB-to-ORB.
Il
General Inter-ORB Protocol specifica un insieme di formati di messaggi
e comuni rappresentazioni dati per la comunicazione tra ORB. I tipi
di dato definiti da OMG sono mappati in un messaggio di rete flat (CDR
– Common Data Representation).
GIOP
definisce un formato multi ORB di riferimento ad un oggetto remoto, l’Interoperable
Object References (IORs). L’informazione contenuta e specificata dalla
struttura dello IOR assume significato indipendentemente dall’implementazione
dell’ORB, consentendo ad un’invocazione di transitare da un ORB ad un altro.
Ogni ORB, fornisce un metodo object_to_string che consente di ottenere
una rappresentazione stringa dello IOR di un generico oggetto.
Vista
la diffusione di TCP/IP, comunemente viene usato l’Internet Inter-ORB Protocol
(IIOP) che specifica come i messaggi GIOP vengono scambiati su TCP/IP.
IIOP viene considerato il protocollo standard CORBA e quindi ogni ORB deve
connettersi con l’universo degli altri ORB traslando le request sul e dal
backbone IIOP.
Tools ed implementazioni
CORBA
Per
realizzare un’applicazione che utilizzi il middleware definito da OMG bisogna
in primo luogo disporre di un prodotto conforme alle specifiche. La garanzia
che viene fornita è comunque quella di scrivere codice utilizzabile
con differenti prodotti CORBA.
Questo
è vero solo in parte, in quanto, essendo lo standard dinamico e
complesso, lo scenario dei prodotti attualmente disponibili è in
continuo divenire ed il livello di aderenza dei singoli prodotti alle specifiche
non è quasi mai completo. In ogni caso è sempre possibile
utilizzare CORBA in maniera tale da garantire un’elevata portabilità.
E’ necessario comunque prestare molta attenzione alla scelta dell’ORB da
utilizzare in quanto questi differiscono sia come prestazioni, sia come
funzionalità fornite.
Nei
prossimi articoli ritorneremo sul tema, presentando gli ORB più
interessanti tra i prodotti freeware e commerciali.
Interface Definition
Language
CORBA
fornisce una chiara separazione tra ciò che è relativo all’interfaccia
di un oggetto e la sua implementazione. In modo molto simile a quanto accade
in RMI, il client non si deve occupare in modo diretto dei dettagli di
implementazione, ma solo dell’interfaccia implementata dall’oggetto che
intende utilizzare.
In
un middleware distribuito tutti gli oggetti, compresi quelli di infrastruttura,
sono trattati come interfacce. Questo è sia una valida scelta di
design, sia un’esigenza di distribuzione: un client tipicamente non conosce
e non deve conoscere l’implementazione di un oggetto destinato ad essere
eseguito su una macchina server.
Questa
considerazione ha una valenza ancora maggiore in un contesto tecnologico
che consente ad esempio il dialogo tra oggetti Java e procedure Cobol che
per natura probabilmente risiederanno addirittura su macchine ad architetture
differenti.
Poiché
CORBA è trasparente rispetto al linguaggio, OMG ha definito nelle
sue specifiche un nuovo linguaggio interamente descrittivo (IDL), destinato
alla definizione delle interfacce degli oggetti CORBA. In momenti successivi
sono stati definiti i differenti mapping tra i vari linguaggi di programmazione
ed IDL. E’ da notare che in molti dei linguaggi utilizzabili con CORBA
non esiste il concetto di interfaccia (ad esempio COBOL e C).
Un
oggetto remoto quindi, indipendentemente dal fatto che sia applicativo
o appartenente all’infrastruttura (l’ORB, i servizi, …), per essere utilzzato
in un middleware CORBA, deve essere in primo luogo definito mediante IDL:
nel caso di un oggetto applicativo la definizione sarà a carico
dello sviluppatore, nel caso di un oggetto di infrastruttura ci viene fornita
da OMG.
Ecco
ad esempio parte della definizione IDL dell’ORB:
//
IDL
module
CORBA {
interface
ORB {
string object_to_string (in Object obj);
Object string_to_object (in string str);
Object resolve_initial_references (in ObjectId
identifier) raises (InvalidName);
// ecc…
};
};
La
definizione IDL di un oggetto permette di specificare solo gli aspetti
relativi alla sua interfaccia, si potranno quindi definire: le signature
dei metodi, le eccezioni che questi rilanciano, l’appartenenza ai package,
costanti e strutture dati manipolate dai metodi.
Data
la definizione IDL, sarà necessario utilizzare il compilatore fornito
a corredo dell’ORB. Dalla compilazione si otterranno un buon numero di
file .java, fra cui stub, skeleton ed altri contenenti codice di supporto
per l’aggancio all’ORB. A partire dai file generati, sarà possibile
realizzare l’opportuna implementazione Java.
Conclusioni
In
questo articolo abbiamo presentato una breve panoramica sullo standard
CORBA. A partire dal prossimo mese inizieremo a scendere nei dettagli affrontando
il mapping IDL to Java
|