CORBA
Transkrypt
CORBA
Budowa aplikacji sieciowych Common Object Request Broker Architecture (CORBA) dr Zbigniew Lipiński Instytut Matematyki i Informatyki ul. Oleska 48 50-204 Opole [email protected] Standard Corba CORBA jest komercyjnym standardem Object Management Group (OMG). http://www.omg.org/ Głównym celem grupy OMG jest upowszechnianie technologii zorientowanych obiektowo służących budowie dużych, rozproszonych systemów informatycznych. Aby zrealizować swoją misję OMG stworzyła Model Referencyjny OMA, Object Management Architecture Reference Model, definiujący standard architektury rozproszonych systemów Informatycznych, podstawy dla innych standardów i specyfikacji: • Meta Object Facility (MOF) specification, • Unified Modeling Language (UML) specification, • XML Metadata Interchange (XMI) specification, • Common Warehouse Metamodel (CWM) specification, • Common Object Request Broker Architecture (CORBA) specification, ułatwiających tworzenia aplikacji w środowisku rozproszonym. Standard Corba W modelu referencyjnym OMA komponenty systemu klient, serwer, baza danych, interfejs są obiektami. Obiektem jest dowolna encja która dostarcza usług żądanych przez klienta. Główną zasadą modelu OMA jest to, że każdy obiekt jest albo obiektem żądającym usługi (klientem), obiektem realizującym usługę (serwerem) lub jednym i drugim. Podstawowym elementem architektury w modelu OMA jest broker poprzez który obiekty komunikują się między sobą. Komunikacja między obiektami odbywa sie poprzez interfejsy. Technologie standardu Corba System rozproszony to system typu klient-serwer w którym występuje duża liczba obiektów typu klient i serwer (multitier client-server system) i które współpracują ze sobą w celu wykonania jakiegoś zadania (np. dostarczenia usługi). Corba jest implementacją warstwy pośredniej (middleware layer) w trójwarstwowej architekturze systemu informatycznego: • warstwa prezentacji (presentation layer), • warstwa pośrednia (middleware, buisness logic layer), • warstwa danych (data layer). Technologie standardu Corba Technologia wykorzystana do opracowania standardu Corby jest: • zorientowana obiektowo, • oparta o zorientowane obiektowo interfejsy, interfejsy oddzielone są od implementacji obiektów (obiektów w części klienta, serwera, brokera) , • niezależna od platformy systemowej, • niezależna od języka w którym implementowane są aplikacje (klient, serwer), • niezależna od lokalizacji klienta i serwera. Zadaniem brokera jest odebrać zapytanie (request) od klienta, znaleźć serwer, przekazać zapytanie na serwer, przekazać odpowiedź klientowi. Broker Corby Zadania brokera: • zarządzanie połączeniem klient-serwer, • zarządzanie pamięcią, • przekazywanie zapytań i odpowiedzi między klientem a serwerem, • kontrola dostępu do usług, • obsługa błędów w komunikacji między klientem a serwerem, • zarządzanie jakością połączenia (QoS). Model OMA (Object Management Architecture) W modelu OMA rozróżnia się cztery kategorie interfejsów: • Object Services, interfejsy wykorzystywane przez aplikacje pracujące w środowisku rozproszonym. • Common Facilities, interfejsy do usług wykorzystywanych przez aplikacje niezależnie od ich komercyjnego zastosowania. • Domain Interfaces, interfejsy specyficzne dla aplikacji z konkretnych podobszarów funkcjonalnych. • Application Interfaces, niestandaryzowane interfejsy dla konkretnych aplikacji. Model Referencyjny OMA rozróżnia cztery kategorie obiektów: • Obiekty ORB (Object Object Request Broker), Broker • Obiekty usług (CORBAservices), • Obiekty standardowych usług (Common Facilities - CORBAfacilities), • Obiekty aplikacji (Application Objects). Obiekty Corby Obiekty Corby są to obiekty z interfejsami zdefiniowanymi w języku IDL. Obiekty Corby mają różną reprezentację po stronie serwera i klienta: • Implementacja Obiektów Corby po stronie serwera nazywa sie servant’em (aplikacja ‘serwującą’ usługi). Serwer używa obiektów Corby zaimplementowanych w konkretnym języku (np. C++, Java). Klasa w której zaimplementowany jest dany obiekt Corby nazywa sie ‘implementation class’. Servant jest instancją klasy implementującej (implementation class) obiekt Corby w konkretnej aplikacji (uwaga: servant nie jest Obiektem Corby, jest implementacja obiektu Corby). • Klient tworzy obiekt proxy w celu wykorzystania obiektów na serwerze (servant’ow). Klient który chce wykorzystać obiekt zaimplementowany przez serwer (wywołać servant’a) przekazuje wszystkie zapytania (requests) poprzez brokera (ORB). Obiekty Corby Schemat generowania zapytań (requests) przez klienta do serwera wygląda następująco: • klient wywołuje lokalnie metodę na obiekcie proxy, • ORB ‘pakuje’ parametry z jakimi została wywołana dana metoda i przekazuje na server, • ORB wywołuje właściwą metodę na servan’cie, • ORB zwraca wynik działania metody na serwerze do klienta. Servant musi być połączony z ORB tak, aby ORB mógł wywoływać metody na servan’cie gdy klient generuje zapytanie (request). To połączenie jest realizowane poprzez Portable Object Adapter (POA). POA decyduje który servant będzie wywołany gdy przychodzi żądanie od klienta i wywołuje danego servant’a. Konfiguracja i kontrola połączenia servant-ORB odbywa sie za pomocą POA Manager’ów. Obiekty POA Fazy tworzenia obiektu POA na serwerze i budowy komunikacji z servant’em: • Aplikacja na serwerze pobiera referencje od root POA. • Aplikacja tworzy Policy dla tworzonego POA (przykłady policies: thread policy, lifespan policy, object uniquenes policy). • Aplikacja tworzy ‘child’ POA z root POA (za pomocą metody create_POA() ). • Tworzenie i aktywowanie servanta. • Aktywowanie POA Managera (POA Manager to obiekt który kontroluje stan POA, tzn. kontroluje czy żądania klienta są kolejkowane, przetwarzane czy odrzucone). Aktywowanie POA Managera następuje poprzez wywołanie metody activate(): rootPOA.the_POAManager().activate(); Reguły zarządzania obiektami Policy (Policies) to zbiór obiektów przypisanych root POA do kontroli zachowań POA i obiektów którymi POA zarządza (POA wygenerowane z POA rodzica nie dziedziczą Policy). W wersji specyfikacji Corba 2.0 dodano protokół Internet inter-ORB Protocol (IIOP) wykorzystywany do przesyłania widomości przez Internet. Protokół IIOP jest implementacją dla TCP/IP abstrakcyjnego protokołu General inter-ORB protocol (GIOP), tzn. IIOP wykorzystuje rodzinę protokołów TCP/IP poniżej warsty Sesji modelu OSI. Specyfikacje standardu Corba Standard Corby obejmuje następujące specyfikacje: • Specyfikacja brokera, Object Request Broker (ORB) Core Specification • Specyfikacja protokołów komunikacyjnych GIP, IIOP (Interoperbillity GIOP, IIOP Specification) • Specyfikacja języka IDL (Interface Definition Languae spcification) • Specyfikacje ‘mapowania’ języka IDL na języki programowania (np. C++, Java, Smaltalk, Ada, ...) • Specyfikacja interfejsów SII, DII (Static Interface Invocation, Dynamic Invocation Interface specification) • Specyfikacja interfejsów SSI, DSI (Static Skeleton Interface, Dynamic Skeleton Interface) • Specyfikacje POA (Portable Object Adapter specification) • Zbiór specyfikacji serwisów Corby. Brokerzy i narzędzia Corby Przykładowe narzędzia (kompilatory IDL, brokerzy) do budowy aplikacji w Corbie: • Progress® Orbacus, Progress® Orbix http://web.progress.com/ • Visibroker® http://www.borland.com/ Zgodny ze specyfikacją Corba 3.0. Interpeter IDL dla Java, C+, C#. • The Inter-Language Unification system (ILU) is a multi-language object interface system ftp://ftp.parc.xerox.com/pub/ilu/ilu.html • omniORB, http://omniorb.sourceforge.net/ • MICO, http://www.mico.org/ Aplikacja klient-serwer typu ‘Hello world’ w Corbie Krok 1. Plik IDL Definicja interfejsu ‘Hello’ odpowiada definicji abstrakcyjnej klasy w jezyku C++ lub definicji interfejsu w języku Java. Interface Hello zawiera operacje Hello(). Operacja Hello() nie ma argumentów i nie zwraca żadnych wartości. // Hello.idl interface Hello { void say_hello(); void shutdown(); }; Krok 2. Konwersja pliku Hello.idl na język C++. Należy wykonać polecenie .\> idl Hello.idl Wynik konwersji: Hello.h, Hello.cpp, Hello_skel.h i Hello_skel.cpp. Aplikacja klient-serwer typu ‘Hello world’ w Corbie Krok 3. Implementacja serwera. Definicja klasy Hello_impl (plik: Hello_impl.h). Definicja operacji say_hello() (plik: Hello_impl.cpp) dla interfejsu Hello. // Hello_impl.h #ifndef HELLO_IMPL_H #define HELLO_IMPL_H #include <Hello_skel.h> class Hello_impl : public POA_Hello, public PortableServer::RefCountServantBase { CORBA::ORB_var orb_; // The ORB PortableServer::POA_var poa_; // The servants default POA public: Hello_impl( CORBA::ORB_ptr orb, PortableServer::POA_ptr poa ); virtual void say_hello() throw (CORBA::SystemException); virtual void shutdown() throw (CORBA::SystemException); virtual PortableServer::POA_ptr _default_POA(); }; #endif Aplikacja klient-serwer typu ‘Hello world’ w Corbie Krok 3. Implementacja serwera. Definicja klasy Hello_impl (plik: Hello_impl.h). Definicja operacji say_hello() (plik: Hello_impl.cpp) dla interfejsu Hello. // Hello_impl.cpp #include <OB/CORBA.h> #include <Hello_impl.h> #ifdef HAVE_STD_IOSTREAM using namespace std; #endif // Hello_impl constructor Hello_impl::Hello_impl( CORBA::ORB_ptr orb, PortableServer::POA_ptr poa ) : orb_(CORBA::ORB::_duplicate(orb)), poa_(PortableServer::POA::_duplicate(poa)) {} // Hello_impl public member implementation void Hello_impl::say_hello() throw(CORBA::SystemException) { cout << "Hello World!" << endl; } void Hello_impl::shutdown() throw(CORBA::SystemException) { orb_ -> shutdown(false); } PortableServer::POA_ptr Hello_impl::_default_POA() { return PortableServer::POA::_duplicate(poa_); } Aplikacja klient-serwer typu ‘Hello world’ w Corbie Defnicja głównego programu serwera (plik: Server.cpp). // Server.cpp #include <OB/CORBA.h> #include <OB/BootManager.h> #include <Hello_impl.h> #include <stdlib.h> #include <errno.h> #ifdef HAVE_FSTREAM # include <fstream> #else # include <fstream.h> #endif #ifdef HAVE_STD_IOSTREAM using namespace std; #endif Aplikacja klient-serwer typu ‘Hello world’ w Corbie Inicjacja ORB i BOA poprzez deklaracje wskaznikow typu CORBA_ORB_var i CORBA_BOA_var Parametry argc, argv inicujące wskaźniki są specyficzne dla brokera ORBACUS. Deklaracja obiektu p klasy Hello_var Serwer przy pomocy operacji impl_is_ready informuje BOA ze jest gotowy przetworzyć zapytanie klienta. int run(CORBA::ORB_ptr orb, int /* argc */, char* argv[]) { // Resolve Root POA CORBA::Object_var poaObj = orb -> resolve_initial_references("RootPOA"); PortableServer::POA_var rootPOA = PortableServer::POA::_narrow(poaObj); // Get a reference to the POA manager PortableServer::POAManager_var manager = rootPOA -> the_POAManager(); // Create implementation object Hello_impl* helloImpl = new Hello_impl(orb, rootPOA); PortableServer::ServantBase_var servant = helloImpl; Hello_var hello = helloImpl -> _this(); // Resolve the BootManager and register the server CORBA::Object_var obj = orb -> resolve_initial_references("BootManager"); OB::BootManager_var bootManager = OB::BootManager::_narrow(obj); PortableServer::ObjectId_var oid = PortableServer::string_to_ObjectId("Hello"); bootManager -> add_binding(oid, hello); // Save reference CORBA::String_var s = orb -> object_to_string(hello); const char* refFile = "Hello.ref"; ofstream out(refFile); if(out.fail()) { cerr << argv[0] << ": can't open `" << refFile << "': “ << strerror(errno) << endl; return EXIT_FAILURE; } out << s << endl; out.close(); // Run implementation manager -> activate(); orb -> run(); return EXIT_SUCCESS; } Aplikacja klient-serwer typu ‘Hello world’ w Corbie // Server.cpp cd. int main(int argc, char* argv[], char*[]) { int status = EXIT_SUCCESS; CORBA::ORB_var orb; try { orb = CORBA::ORB_init(argc, argv); status = run(orb, argc, argv); } catch(const CORBA::Exception& ex) { cerr << ex << endl; status = EXIT_FAILURE; } if(!CORBA::is_nil(orb)) { try { orb -> destroy(); } catch(const CORBA::Exception& ex) { cerr << ex << endl; status = EXIT_FAILURE; } } return status; } Aplikacja klient-serwer typu ‘Hello world’ w Corbie Krok 4. Implementacja klienta. // Client.cpp #include <OB/CORBA.h> #include <Hello.h> #include <stdlib.h> #ifdef HAVE_STD_IOSTREAM using namespace std; #endif int run(CORBA::ORB_ptr orb, int /* argc */, char* argv[]) { CORBA::Object_var obj; // Get "hello" object try { obj = orb -> string_to_object("relfile:/Hello.ref"); } catch(const CORBA::BAD_PARAM&) { } if(CORBA::is_nil(obj)) { cerr << argv[0] << ": cannot read IOR from Hello.ref" << endl; return EXIT_FAILURE; } Hello_var hello = Hello::_narrow(obj); assert(!CORBA::is_nil(hello)); // Main loop cout << "Enter 'h' for hello, 's' for shutdown or 'x' for exit:\n"; char c; do { cout << "> "; cin >> c; if(c == 'h') hello -> say_hello(); else if(c == 's') hello -> shutdown(); } while(cin.good() && c != 'x'); return EXIT_SUCCESS; } Aplikacja klient-serwer typu ‘Hello world’ w Corbie // Client.cpp cd. int main(int argc, char* argv[], char*[]) { int status = EXIT_SUCCESS; CORBA::ORB_var orb; try { orb = CORBA::ORB_init(argc, argv, "Hello-Client"); status = run(orb, argc, argv); } catch(const CORBA::Exception& ex) { cerr << ex << endl; status = EXIT_FAILURE; } if(!CORBA::is_nil(orb)) { try { orb -> destroy(); } catch(const CORBA::Exception& ex) { cerr << ex << endl; status = EXIT_FAILURE; } } return status; } Aplikacja klient-serwer typu ‘Hello world’ w Corbie Krok 5. Kompilacja projektu. 5.1 Utwórz projekt Hello: Pliki projektu: Hello.h, Hello.cpp, Hello_skel.h, Hello_skel.cpp Konfiguracja: dodać link do bibliotek: ob.lib, wsock32.lib 5.2 Utwórz projekt Serwer. 5.3 Utwórz projekt Klient. Klient i serwer muszą być linkowane z plikiem Hello.o (po kompilacji Hello.cpp). Pliki Hello_skel.cpp i Hello_impl.cpp wymagane sa przez serwer. Krok 6. Uruchomienie aplikacji.