Introduzione all’Architettura CORBA Tito Flagella - [email protected] L’Interoperabilità • Individuare paradigmi indipendenti dalla piattaforma utili per risolvere un’ampia classe di problemi • Nascondere il più possibile la complessità senza sacrificare le prestazioni • Individuare uno strato di sviluppo omogeneo realizzato sui diversi sistemi eterogenei 2 La Programmazione di sistemi eterogenei • Scrivere programmi che comunicano via socket – Gestire l’eterogeneità a livello applicativo • Scrivere programmi che comunicano via RPC – Anni ‘80 • Chiamare oggetti remoti come se fossero locali – A partire dagli anni ’90 3 Il paradigma RPC Client Stub ORB Skeleton Server 4 CORBA: uno standard per le Applicazioni Distribuite • • • • Curato da OMG, più di ottocento membri... Prima versione adottata in ottobre 91 Prime implementazioni dal 93 Molte le implementazioni, anche free, per qualunque linguaggio • Interoperabilità assicurata attraverso la standardizzazione dei protocolli Inter Orb (GIOP, IIOP, etc...) 5 Object Management Architecture 6 CORBA: funzionalità di base (1) • CORBA è un'ambiente utile per: – integrare applicazioni parzialmente già esistenti – costruire nuove applicazioni distribuite 7 CORBA: funzionalità di base (3) • Interfacce e Dati sono descritti in un apposito linguaggio indipendente dall’implementazione, detto Interface Definition Language (IDL) • Lo standard CORBA include la definizione del binding da IDL ai linguaggi di implementazione, come C, C++, Java, COBOL, .... 8 CORBA: funzionalità di base (2) • Un tipico sistema basato su CORBA è composto da un'insieme di programmi client che accedono a servizi distribuiti sulla rete • Architettura peer-to-peer, non client-server – un client può definire servizi – le chiamate al servizio del client si chiamano callback – sono spesso usate per la notifica asincrona del cambio di dati sul server 9 CORBA: funzionalità di base (4) • Le chiamate per default sono bloccanti (stessa semantica dei linguaggi di programmazione) • Possono però anche essere di tipo asincrono: – dichiarazioni oneway in IDL – uso di servizi specifici: event-service, notification service, message service 10 L’architettura dell’ORB 11 L’architettura CORBA 12 Architettura dell’ORB, lato client • Un Client effettua una richiesta (statica o dinamica), utilizzando un "Object Reference" per individuare il servizio • Il Client deve conoscere il tipo dei parametri • Nel caso statico usa lo stub, nel dinamico l’Interface Repository (un servizio che consente la consultazione a run-time delle interfacce) 13 Architettura dell’ORB, lato server • Sul lato server, il codice dell'object implementation viene invocato dall’OA tramite una "up-call”: – associata a uno skeleton statico generato dal compilatore idl (SSI) – costruita dinamicamente, utilizzando l'Interface Repository (DSI) 14 Trasparenza dei meccanismi dinamici • La semantica dell'ORB per l'operazione statica o dinamica è esattamente la stessa • Il server non ha modo di verificare se la richiesta sia stata statica o dinamica • Il client non ha modo di verificare se il server stia usando SSI o DSI 15 L’architettura dell’ORB, lato server • L’Object Adapter tratta aspetti quali: – generazione e interpretazione dell'Object Reference – corrispondenza tra oggetto e processo che ne implementa il servizio – invocazione dei metodi – attivazione, disattivazione delle implementazioni 16 Uso dello IOR tra client e server (1) • Il sistema più elementare per stabilire una connessione diretta tra client e server è l'uso dello IOR • Uno IOR, Interoperable Object Reference, costituisce un indirizzo univoco corrispondente ad un'oggetto CORBA 17 Uso dello IOR tra client e server (2) • Il server genera uno IOR per l'oggetto da rendere accessibile e lo comunica ai potenziali clienti tramite uno dei seguenti mezzi: – file system condiviso – pubblicazione su un server Web trasmissione off-line – uso del Naming Service 18 Struttura dell’IOR (nel caso di IIOP) 19 Il linguaggio IDL • E’ l’astrazione usata in CORBA per separare le interfacce degli oggetti dalle loro implementazioni • Parte dello Standard CORBA di OMG • Ne esistono numerose altre versioni • Standardizzato come standard ISO 20 Il Linguaggio IDL (2) • E` utilizzato per descrivere le interfacce degli oggetti e i tipi dei parametri • IDL non e` un linguaggio di programmazione – non serve per implementare gli oggetti o per realizzare client che accedano agli oggetti • IDL e` volutamente semplice per essere facilmente mappabile a linguaggi di programmazione poco evoluti 21 Le Interfacce IDL (1) interface FrontOffice { readonly attribute string name; readonly attribute unsigned long numberOfSeats; Price getPrice(in Place chosenPlace); boolean bookSingleSeat(in Place chosenPlace, in string creditCard); }; 22 Le Interfacce IDL (2) • L'interfaccia IDL di un oggetto contiene tutte le informazioni utili per realizzare un client che lo usi • Una tipica interfaccia contiene la specifica di: – le operazioni supportate dall'interfaccia (compresa la specifica dei tipi dei parametri e del valore di ritorno) – gli attributi dell'interfaccia 23 Le Interfacce IDL (3) • Ogni procedura specifica il nome, il tipo e la modalita` di trasmissione dei suoi parametri – Es: boolean checkIfOpen(in Date when, out Date nextAvailableDate) • La modalità di trasmissione può essere: – in: il parametro viaggia dal chiamante (client) al chiamato (server) – out: il parametro viaggia dal server al client – inout: il parametro viaggia in entrambe le direzioni 24 Alcune caratteristiche dell'IDL confrontate con il C++ • Tutte le definizioni IDL sono public • Non esiste il concetto di private o protected, che riguardano l'implementazione più delle interfacce • Mancanza di costruttori o distruttori: sostituiti dalle factory, oggetti capaci di creare altri tipi di oggetti • L'overloading dei nomi delle operazioni è illegale – funzionalità utile ma difficile da tradurre in linguaggi che non la supportano 25 Il compilatore IDL • Il compilatore IDL traduce queste specifiche in API e definizione di tipi dipendenti dal linguaggio scelto 26 I binding IDL • Specificano come usare CORBA da ognuno dei linguaggi supportati – Esistono specifiche ufficiali per: • C, C++, Smalltalk, COBOL, ADA e Java – CORBA è comunque giè utilizzabile anche da: • Visual Basic, Modula3, Perl, TCL, Python, Dylan, Oberon e Objective-C • Enormi differenze nelle difficoltà di programmazione a seconda dei linguaggi usati 27 Binding a C++ • In C/C++ ci si deve preoccupare di – allocazione/deallocazione degli oggetti (è suggerito l’uso di smart pointer generati dal compilatore IDL) – Uso di tipi CORBA per i tipi primitivi (int, long, …) 28 Binding a Java • In Java la programmazione è molto più elegante • L’uso di CORBA diventa quasi completamente trasparente • La mancanza dell’ereditarietà multipla complica l’implementazione dell’ereditarietà in IDL 29 CORBA per le applicazioni Internet Internet Rete Servizi Pubblici Utenza Web Browser Applet Documenti http http SQL, jdbc,... Web Server Web Browser Backend DB CGI, ISAPI,NSAPI, Servlet, ASP DB ad Oggetti iiop Orblet iiop Oggetti CORBA Sistemi Legacy Outbound Firewall Inbound Firewall 30 Sviluppo di un’applicazione CORBA • • • • Definire l’interfaccia della classe server Realizzarla in idl Compilare l’IDL per produrre stub e skeleton Scrivere il codice del server e linkarlo con gli skeleton del servizio • Creare un’istanza del server e collegarla all’ORB • Scrivere il codice del client e linkarlo con gli stub del servizio 31 L’esempio del Counter • Problema: Creare un oggetto counter he esponga un metodo increment(). • Ogni chiamata a increment() aggiunge 1 al contatore interno dell’oggetto, e restituisce il nuovo valore del contatore. 32 Step 1: Definire le Interfacce Il codice del Server public class Counter { private int sum; public Counter () { sum = 0; } public int increment () { sum ++; return sum; } } Il codice del Client public class CountTest { public static void main (String args[]) { Counter myCount = new Counter (); for (int i=0; i<100; i++) System.out.println (myCount.increment()); } } 33 Step 2: Interfaccia IDL module CounterPackage { interface Counter { long increment (); }; }; 34 Step 2: scrivere l’IDL • Mapping tra tipi Java e IDL Java boolean char String int long float IDL boolean char string long long long float module CounterPackage { interface Counter { long increment (); }; } 35 Step 3: Compilazione IDL %> idlj -oldImplBase -fserver count.idl Genera skeleton da linkare al server Counter.java _CounterImplBase.java CounterOperations.java %> idlj -fclient login.idl Genera stub da linkare al client _CounterStub.java CounterHolder.java CounterHelper.java 36 Step 3: Compilazione IDL (2) package _CounterPackage; /** * _CounterPackage/Counter.java . * Generated by the IDL-to-Java compiler (portable), version "3.2" * from counter.idl * Wednesday, May 3, 2006 7:49:32 AM CEST */ public interface Counter extends CounterOperations, org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity { } // interface Counter 37 Step 4: Implementare il Servant • Identica alla versione sequenziale ma estende lo skeleton import _CounterPackage.*; public class Counter extends _CounterImplBase { private int sum; public Counter () { sum = 0; } public int increment () { sum ++; return sum; } } 38 Step 5: Creare l’istanza del Server – – – – Inizializzare l’ORB Creare un’istanza dell’oggetto server (servant) Fare il bind dell’oggetto all’ORB Ottenere e pubblicare l’IOR per quest’oggetto 39 Il codice del Server import org.omg.CORBA.*; import java.io.*; public class CounterServer { public static void main (String args[]) ORB orb = ORB.init (args, null); // Counter aCounter = new Counter (); // orb.connect (aCounter); // throws Exception { Initialise ORB. Create new counter. Register counter with ORB. String stringobjectref = orb.object_to_string(aCounter); PrintWriter fout = new PrintWriter (new FileWriter("ior.txt"),true); fout.println (stringobjectref); System.out.println (stringobjectref); // Orb ref. java.lang.Object sync = new java.lang.Object (); synchronized (sync) { sync.wait(); } } } 40 Step 6: Implementazione del Client • Inizializzazione dell’ORB • Accesso all’ORB per creare un proxy/stub per l’accesso all’oggetto remoto • Invocare il metodo sullo stub 41 Il Codice del Client import _CounterPackage.*; import org.omg.CORBA.*; public class CountTest { public static void main (String args[]) { ORB orb = ORB.init (args,null); _CounterPackage.Counter myCount = CounterHelper.narrow (orb.string_to_object(args[0])); for (int i=0; i<100; i++) System.out.println (myCount.increment()); } } 42