Interoperabilitate Si Consistenta In Aplicatii Distribuite Folosind Corba

Interoperabilitate si consistenta in aplicatii distribuite folosind CORBA

CUPRINS

INTRODUCERE

Capitolul 1 NOTIUNI CHEIE

1.1 Scurt istoric

1.2 Object Request Broker

1.2.1 Adaptorul obiect de baza

1.3 Serviciile CORBA

1.4 Facilitatile CORBA

1.5 Concepte legate de limbajul IDL

1.6 Cum este independenta de limbaj dobandita

1.7 Probleme de proiectare

1.8 Interfata pentru Invocare Dinamica

1.9 Interoperabilitatea

1.10 Protocoale pentru asigurarea interoperabilitatii

1.11 Mai mult de un ORB

1.12 IOR

Capitolul 2 OBTINEREA DE REFERINTE SI INTERFETE ALE OBIECTELOR

2.1 Serviciul de Nume

2.2 De ce sa folosim Serviciul de Nume

2.3 Ce este un nume

2.4 Crearea Contextelor

2.5 Stergerea Contextelor si Numelor

2.6 Rezolvarea numelor

2.7 Metadate in CORBA

2.8 Rolul limbajului IDL in oferirea interoperabilitatii

2.9 Contractul IDL

2.10 Structura limbajului CORBA IDL

2.11 Un exemplu de interfata specificata in IDL

2.12 Type Code-uri CORBA (Date autodescriptive

2.13 Depozitarul de Interfete(Interface Repository

2.14 De ce este nevoie de un Depozitar de Interfete

2.15 Implementare

Cum gasesc o interfata

Interfete ce apartin diferitor ORB-uri

Capitolul 3 INTERFATA PENTRU INVOCARE DINAMICA

Libertatea oferita de invocarile dinamice

Pasii

3.3 Interfetele de Invocare Dinamica

3.4 Scenarii pentru invocarea dinamica

Capitolul 4 APLICATIA CLIENT GRAFIC CORBA

4.1 Structura generala

4.2 Implementare

Introducere

Cuvant inainte

World Wide Web a adus treptat pe langa beneficii si un continut extrem de mare de informatie fara valoare.In acelasi timp in el se gaseste si un uimitor continut de valoare de la fotografii ale soarelui pana la dictionarii ale unor limbi stravechi.De ce exista oare acest paradox?Motivul este simplu:postarea informatiei (indiferent de utilitate) este necostisitoare iar Web-ul este inca in cea mai mare parte static.Chiar si paginile dinamice care ofera continut dinamic tind sa foloseasca mecanisme de cautare si stocare a informatiei in baze de date statice.

Urmatorul pas al Internet-ului e indicat ca fiind unul al conexiunilor al popularului Web browser la “insule de informatie” personale, corporative, nationale sau internationale precum si conexiuniile la diverse servicii.Aceste servicii vor fii de fapt baza noului Web.Cele mai intalnite vor fi:serviciile de comunicatie si serviciile computerizate de la servicii pentru managementul obiectelor electronice din casa pana la servicii inter-corporative de schimb de date.Care sunt atunci lipsurile tehnogice care ne tin sa nu indeplinim acest lucru maret?Pricipalul motiv consta in modelul arhitectural sarac al programarii majoritatii Web service-urilor de astazi.Iar unul dintre defecte este Common Gateway Interface(CGI) un protocol care permite serverelor rutarea continutului formularelor HTML la aplicatii aflate pe server.HTTP cu CGI formeaza un protocol greu,incet si fara stare de aceea nu este potrivit pentru programarea orientata obiect a serviilor web.

In timp ce mari eforturi s-au facut in domeniul programarii distribuite si orientate obiect un rol important il are organizatia de promovare a standardelor Object Management Group(OMG) formata din peste 800 de firme de diferite renume,infiintata in anul 1991.Sistemele construite pe Arhitectura de Management al Obiectului (OMA) si in particular CORBA adreseaza probleme de integrare in cadrul domeniului de folosinta al aplicatiei,portabilitatea si interoperabilitatea independente de platforma.

De ce CORBA?

Ceea ce face CORBA(Common Object Request Broker Arhitecture) asa de importanta este faptul ca defineste un middleware care are potentialul in a subsuma toate formele de middleware client/server existente.Magistrala CORBA defineste “forma” componentelor care locuiesc in cadrul ei si cum interactioneaza intre ele.Intregul sistem ce foloseste tehnologia CORBA se descrie singur prin intermediul pseudo-limbajului IDL(Interface Definition Language).Deasemenea specificatia unui serviciu este intodeauna separata de implementarea sa.Acest lucru furnizeaza un grad de interoperabilitate ridicat prin faptul ca permite integrarea in cadrul magistralei a sistemelor(programelor) deja existente.

Interoperabilitatea si nu este singurul avantaj al arhitecturii(CORBA).Desi a fost proiectata sa ofere cadrul in care componente inteligente se descopera una pe alta si interactioneaza pe o magistrala pentru comunicatia intre obiecte,mai sunt specificate si o serie de servicii relative la magistrala folosite in crearea si stergerea obiectelor,accesarea lor prin nume,stocarea lor in locuri persistente,externalizarea starii lor si definirea ad-hoc de relatii intre obiecte.

Obiectiv

Scopul lucrarii este deci furnizarea unui cadru de prezentare a notiunilor de baza ce trebuiesc cunoscute pentru a dezvolta un sistem software independent de platforma ,mediu de comunicare si limbaj de programare avand ca finalitate proiectarea de parti a unui astfel de sistem care ar putea fi utilizat in cadrul unei inteprinderi pentru utilizarea oricarui tip de serviciu implementat de asemenea pe baza arhitecturii CORBA in cadrul inteprinderii respective.Un exemplu similar dar pe o arhitectura clasica care nu foloseste CORBA ar fi acela in care dorim sa avem acces la informatia stocata de un server intr-o baza de data.Aici insa pot aparea cateva probleme majore care in arhitectura CORBA fie nu apar fie pot fi rezolvate foarte usor spre exemplu:ce s-ar intampla daca serverul se muta la o alta adresa cum anunta-m aplicatia client,ce ne facem daca dorim sa implementam noi functionalitati ale serverului atunci si aplicatia va trebuii sa se schimbe corespunzator,daca apare un nou sistem software pentru implementarea serverului,etc.

Multe din aceste dependente aplicatie client/aplicatie server sunt rezolvate in CORBA prin introducerea unui strat intermediar cel al pseudo-interfetelor care se comporta ca niste contracte intre server si client adica server-ul sa angajeaza sa furnizeze toate serviciile specificate in pseudo-interfata de care dispune clientul.Uneori clientul nu dispune,nu vrea sa stocheze sau nu stie inca de aparitia aceastei interfete si atunci intervine invocarea dinamica a metodelor(“serviciilor”) care se realizeaza la executie prin descoperirea interfetelor si deci si a semnaturilor metodelor.

Aplicatia va fi implementata in totalitate in limbajul Java si folosind ca broker de obiecte(Object Request Broker) ORB-ul din Java platforma 1.4.2.(platforma de baza).O observatie asupra acestui ORB este aceea ca fata de alte ORB-uri care functioneaza cu Java el nu dispune de un mecanism de stocare al interfetelor pe parte de server(de un Interface Repository) acest lucru ingreunand foarte mult rapiditatea aplicatiei si consider ca e o sursa minora de bug-uri.Alegerea unui ORB nu a depins de mine ci de inteprinderea pentru care acest proiect ar putea fi implementat.Utilitatea aplicatiei consta in apelul dinamic la distanta de metode pentru care nu se cunoaste antetul si nici o metoda de transmitere a parametrilor sau receptionare a rezultatului.

Metoda clasica pentru acest tip de aplicatie consta in apelul metodelor asupra unui obiect pentru care cunoastem fisierul interfata(in limbaj IDL) si care a fost compilat pentru a furniza codul necesar apelului,transimiterii de parametri si receptionarii rezultatului,insa aceasta apelare e formata din urmatoarele cunostiinte mai importante ale clientului:stocarea pentru fiecare obiect a fisierului interfata corespunzator lui,compilarea acestui fisier.Aceasta este cunoscuta in tehnologia CORBA ca invocarea statica a metodelor unui obiect.

Metoda dinamica care e folosita in proiect nu presupune ca clientul sa cunoasca interfata IDL si deci nici sa o compileze insa acest lucru numai daca ORB-ul dispune de un IR.In aplicatia dezvoltata dupa cum am precizat nu dispun de un IR si deci va trebuii sa cunosc fisierul IDL insa partea buna este ca nu va trebuii sa compilez fisierul IDL ci doar sa implementez un mecanism de extragere coerenta din fisier a tuturor datelor necesare pentru a implementa apoi la executie apelul dinamic pe baza fisierului IDL furnizat.

Capitolul 1

Notiuni cheie

1.1Scurt istoric

CORBA (acronimul lui Common Object Request Broker Arhitecture) este cel mai important(si ambitios) proiect demarat de industria software a ultimilor ani.Este produsul unui consortiu numit Object Management Group(OMG) care include peste 800 de companii reprezentand intregul spectru al al industriei software si hardware.

Membrii organizatiei includ majoritatea companiilor furnizoare de TI si m ulte companii end-user. Activitatea sa se realizeaza prin adoptarea de interfete si specificatii de protocoale într-un context adoptat de OMA (Object Management Architecture). Aceste specificatii sunt elaborate de un numar de membrii a caror activitate este colaborativa. OMG îsi orienteaza activitatea pe obiecte distribuite ca vehicul pentru integrarea sistemelor. Beneficiul major la construirea de sisteme distribuite cu obiecte este încapsularea: datele si starile sunt accesibile numai prin intermediul inv ocarii unui set de operatii definite si, în general, nu prin acces direct.

Aceasta face mai simpla cooperarea într-un mediu eterogen (diferite implementari ale aceluiasi serviciu) deoarece diferentele legate de reprezentarea datelor sunt mascate.

Obiectele, ca entitati definite, sunt simplificatoare ale evolutiei sistemului: noile servicii si implementari pot fi astfel introduse deoarece sustin aceleasi operatii ca si serviciile pe care le înlocuiesc. CORBA este componenta centrala a lui OMA si deja exista mai multe implementari comerciale care sunt accesibile.

Magistrala pentru obiecte CORBA definineste forma componentelor care locuiesc in cadrul ei si cum acestea interactioneaza intre ele.Alegand o magistrala deschisa de comunicare practic industria a ales sa creeze un camp de lupta pentru componente.

Din punctul de vedere al programarii distribuite CORBA este important din doua motive:

-simplifica programarea distribuita

-este o notatie standard pentru dezvoltarea aplicatiilor

Un mediu distribuit combina toate diferentele intre sisteme de operare,limbaje de programare si proceseaza locatiile utilizand o abordare orientata obiect.Ca si notatie standard rezolva diferentele intre interfetele software.

Un obiectiv principal pentru OMG este promovarea tehnologiei orientate obiect. Astfel a dezvoltat proiectul major pentru managementul obiectelor Object Management Architecture Reference Model (OMA) in scopul de a raspandii noutatile si de a propune noi tehnologii sau de a aduce modificari celor existente.

Un concept cheie al modelului este ca tehnologia obiect sa aiba trei abilitati:

• Refolosinta

• Portabilitate

• Interoperabilitate

Pentru cunoscatori se aseamana cu o lista pentru tehnologia Java.Exista deja implementari importante ale tehnologiei obiect care adera la aceste reguli si anume brokerii de management al cererilor la obiecte(ORB),modelul distribuit pentru componente obiect(DCOM de la Microsoft) si conectivitate JAVA la bazele de date(JBDC).

1.2 Object Request Broker

Cheia spre CORBA sunt brokerii de obiecte(ORB) care sunt de altfel componenta centrala a modelului OMA.Un principiu de baza in model este acela ca un obiect poate fi un client sau un server in orice moment de timp.Principiul vechi era acela ca un client este diferit de un server.Modelul OMA defineste patru categorii de obiecte:

• ORB –uri (Object Request Broker)

• Obiecte de tip aplicatie

• Obiecte de tip Servicii (CORBAservices)

• Facilitatiile (CORBAfacilities)

Un Object Request Broker (ORB) este o magistrala software folosita pentru manevrarea obiectelor distribuite intr-un mediu heterogen.ORB serveste precum o interfata pentru diferite tipuri de platforme.Este o interfata de comunicare si este neutra fata de limbaje.Totusi trebu) in scopul de a raspandii noutatile si de a propune noi tehnologii sau de a aduce modificari celor existente.

Un concept cheie al modelului este ca tehnologia obiect sa aiba trei abilitati:

• Refolosinta

• Portabilitate

• Interoperabilitate

Pentru cunoscatori se aseamana cu o lista pentru tehnologia Java.Exista deja implementari importante ale tehnologiei obiect care adera la aceste reguli si anume brokerii de management al cererilor la obiecte(ORB),modelul distribuit pentru componente obiect(DCOM de la Microsoft) si conectivitate JAVA la bazele de date(JBDC).

1.2 Object Request Broker

Cheia spre CORBA sunt brokerii de obiecte(ORB) care sunt de altfel componenta centrala a modelului OMA.Un principiu de baza in model este acela ca un obiect poate fi un client sau un server in orice moment de timp.Principiul vechi era acela ca un client este diferit de un server.Modelul OMA defineste patru categorii de obiecte:

• ORB –uri (Object Request Broker)

• Obiecte de tip aplicatie

• Obiecte de tip Servicii (CORBAservices)

• Facilitatiile (CORBAfacilities)

Un Object Request Broker (ORB) este o magistrala software folosita pentru manevrarea obiectelor distribuite intr-un mediu heterogen.ORB serveste precum o interfata pentru diferite tipuri de platforme.Este o interfata de comunicare si este neutra fata de limbaje.Totusi trebuie sa existe o mapare intre limbajul de implementare si pseudo-limbajul IDL(Interface Definition Language).Aceasta mapare este legatura comuna intre obiectele aplicatie,obiectele tip servicii si facilitati.

Obiectele aplicatie sunt programe ale dezvoltatorilor software.Ele interactioneaza cu celelalte componente ale modelului OMA.

Se vor utiliza termenii de ‘client’ si ‘obiect’ pentru a distinge între entitatile care primesc o invocare pentru a executa o operatie (obiectul) si entitatea care trimite cererea (c lientul). Aceste doua aspecte sunt privite doar ca niste roluri pe care le joaca la un moment dat un obiect. Un client poate, el însusi, sa sustina un numar de operatii, iar când acestea sunt invocate, clientul va juca rol de obiect. Cea mai importanta functie a ORB este de a valida un client pentru invocarea unei operatii pe un obiect potential, la distanta. Pentru o astfel de realizare ORB va trebui sa mascheze protocoalele de baza si

activitatea de retea utilizata pentru a trimite invocarea si a primi rezultatele.

Clientul va identifica obiectul tinta prin intermediul unei referinte a acestuia. ORB este responsabil pentru localizarea obiectului, pregatirea datelor necesare pentru respectiva cerere (este posibila necesitatea activarii acestuia) si trecerea datele necesare de la cerere la obiect. Odata ce obiectul a executat operatia identificata prin cerere, daca este nevoie de o reluare, ORB este responsabil de comunicarea acestei necesitati, înapoi la client. ORB consta din mai multe componente logice distincte. Orice (incluzând canalele si structurile IDL), în afara clientului si obiectului sunt considerate ca fiind parte din ORB interfata obiectului adaptat,interfata pentru invocare dinamica,interfata ORB-ului,depozitarul de interfete.

Exista câteva interfete care nu sunt explicit definite de specificatie: interfata dintre nucleul ORB si canalele IDL, interfata dintre adaptorul, obiectului si structura IDL, interfata dintre adaptorul obiectului si nucleul ORB. Prin nedefinirea acestor interfete specificatia CORBA permite mai multe implementari diferite.

De exemplu, o implementare îsi propune sa furnizeze mai multa functionalitate în canalele IDL si adaptorul obiectului si mai putina pe nucleul ORB. Ceea ce este foarte important legat de acesta este ca atât clientul cât si obiectul nu sesizeaza diferente, deoarece CORBA specificat interfetele prin care acestia vor interactiona cu ORB. Astfel CORBA specifica regulile prin care obiectele interactioneaza unele cu altele, prin interfetele definite în IDL. Deci, implementarea obiectelor port dintr-o implementare CORBA la o alta trebuie sa fie triviale. Exista anumite lucruri care pot face ca implementarea obiectelor port sa nu fie triviala. CORBA nu defineste întreaga interfata utilizata de adaptorul obiectului pentru a activa obiecte (a da o definitie completa este dificil deoarece chiar ceea ce constituie activarea poate varia între sisteme de operare):

CORBA permite existenta mai multor alternative pentru adaptorul obiectului, dat defineste interfata furnizata numai pentru una;

Interfetele ORB sunt specificate în IDL cu o descriere în limba engleza a semanticilor fiecarei operatii definite pe interfata. Implementari diferite pot interpreta diferit specificatia redactata în engleza.

Interfata ORB furnizeaza un numar de operatii care pot fi aplicate oricarui obiect. Operatiile furnizate de interfata ORB includ:

operatii care acopera referintele obiectelor la siruri si invers;

operatii de release() si duplicate() pentru gestiunea memoriei utilizate de obiecte si de referintele obiect;

operatia get_interface() necesara pentru interfata de stocare;

operatia de create_request() utilizata în conjunctie cu interfata de invocare dinamica.

Un anumit mediu poate avea mai mult decât un ORB. Astfel, OMG include facilitati care permit obiectelor sa selecteze un ORB la initializarea acestora.

Atât canalele, cât si structurile IDL sunt generate de un program numit ‘stub compiler’ din definitiile IDL ale interfetei. Fiind definite de catre OMG maparea DL pe un numar mare de limbaje, pentru un limbaj dat si o definitie data a interfetei, interfetele canal-client si structura-obiect sunt fixate.

Rolul pe care îl au canalul si structura IDL este de a masca detaliile fundamentelor ORB relativ la aplicatie, astfel încât invocarea la distanta apare ca si invocarea locala. Canalul transmite nucleului de baza ORB bufferul, împreuna cu referinta obiectului. Rutinele invocate de canalul client în nucleul ORB sunt cel mai probabil în acelasi proces ca si canalul IDL si clientul (probabil linkate într-o biblioteca a rularii). Sarcina nucleului ORB este de a localiza obiectul la distanta si de a-l pregati pentru a fi capabil de a primi cererea si în final de a o transmite, astfel încât acesta sa poata executa operatiile adecvate. Sunt de luat în considerare doua cazuri:

cazul în care obiectul la distanta este deja activ

cazul în care obiectul la distanta este pasiv.

În primul caz sarcina nucleului ORB din procesul client este de a localiza adresa IP a masinii pe care se afla obiectul la distanta si numarul portului pe care este vizibil obiectul la distanta. Dupa finalizarea acestui punct, partea client a nucleului ORB va transmite nucleului ORB la distanta bufferul, cu fragmentarea acestuia daca bufferul este prea mare. Nucleele ORB a partii client si a obiectului la distanta trebuie sa poata trata toate defectele care pot sa apara, cum ar fi pierdere sau duplicare de pachete, dând astfel comunicatiei semnificatia de fiabila. Sarcina de a localiza nucleul ORB al obiectelor la distanta poate deveni chiar complicata, daca obiectul la distanta este mobil, pentru aceasta fiind necesara o infrastructura foarte complicata. Aranjamentul bibliotecilor si al proceselor la obiectul la distanta va fi similara cu cea a clientului. În mod tipic obiectul la distanta va fi continut într-un proces linkat cu structura ISDL, adaptorul de baza al obiectului si anumite rutine date cu nucleul ORB. Un proces poate contine mai multe obiecte si structuri IDL (în terminologia ODP ‘capsule’). Odata ce nucleul ORB al obiectului la distanta a primit bufferul si l-a reasamblat corect (daca acesta a fost fragmentat), referinta obiectului decodeaza numele operatiilor si a fiecarui

parametru al acesteia, pentru a determina obiectul care trebuie sa recepteze bufferul. Daca obiectul nu este rezident în ‘capsula’ se va returna o eroare la nucleul ORB al partii clientului, iar restul de buffer este trecut la structura IDL pentru obiect.

Eventual nucleul ORB al clientului va un buffer de reluare. Acesta va verifica faptul ca, într-adevar, clientul este prezent în capsula si va plasa bufferul de reluare la canalul IDL. Canalul IDL va decodifica numele operatiei si al fiecarui parametru al acesteia si va transmite controlul clientului. Invocarea unui obiect la distanta care este pasiv este similara invocarii deja prezentate, dar include un numar de pasi suplimentari în care obiectul la distanta este activat, dupa care lucrurile se deruleaza ca mai sus. Activarea unui obiect în CORBA este responsabilitatea adaptorului obiectului. În practica, adaptorul obiectului poate fi implementat ca o componenta a bibliotecii (linkata cu obiectul si canalul IDL) si o a doua parte este componenta a unui proces ‘daemon’ ORB care ruleaza pe fiecare host. Partea de adaptor obiect care ruleaza în ‘daemon’ ORB va fi partajata de toate obiectele care ruleaza pe host-ul respectiv. Pentru a activa un obiect ‘daemon’ va trebui sa instantieze un proces, sa ruleze o implementare a obiectului pentru orice stare persistenta a acestuia preluata din stocarea persistenta.

Odata ce nucleul ORB al clientului a determinat adresa IP si portul UDP (User Datagram Protocol) al obiectului la distanta, va contacta daemon ORB pe hostul la distanta care este vizibil pe portul UDP deja cunoscut. Daemon ORB trebuie sa transmita la ORB client daca obiectul este activ si vizibil pe vechiul port UDP. Alternativ acesta va returna noul port UDP daca obiectul este pasiv si transmite reactivarea acestuia (vechiul port poate fi deja indisponibil).

Dupa ce nucleul ORB al clientului s-a asigurat de portul UDP pe care poate contacta obiectul la distanta, va transmite cererea dupa mecanismul anterior prezentat. Nu este firesc ca un client sa contacteze daemon ORB pentru obiectul la distanta pentru fiecare invocare. Mai degraba ac esta va contacta servicuil ca în primul pas de utilizare a referintei obiectului, daca a aparut o eroare sau daca nu a utilizat referinta obiectului

mult timp.

Aceasta înseamna ca daca un client face cereri frecvente unui obiect daemon ORB va fi implicat rar. În concluzie, canalul si structura IDL marcheaza multe dintre detaliile neplacut e ale programarii distribuite pentru programator si satisface multe dintre cerintele de transparenta luate în considerare. Pentru programatorii client sintaxa invocarii obiectului la distanta este foarte apropiata de cea a invocarii locale a obiectului. Vor trebui doar sa amplifice codul scris cu exceptii suplimentare (specifice). Programatorii la distanta trebuie doar sa implementeze o operatie pentru fiecare dintre cele definite în IDL pentru interfata. De asemenea, programatorii trebuie sa scrie cod pentru tratarea activarilor si a dezactivarii, adica obiectul necesita stocare persistenta astfel încât dezactivare si activare sa se produca fara pierdere de stare. Modul în care se va produce acest cod este dependent de implementarea ORB si de specificitatea adaptorului obiectului, precum si de serviciul de obiect – persistent.

1.2.1 Adaptorul obiect de baza

OMG specifica detalii ale unui singur adaptor obiect numit adaptorul obiect de baza (BOA). Un ORB poate furniza adaptoare obiect suplimentare. Principalele functii ale BOA sunt:

– generarea si distrugerea de obiecte

– activarea si dezactivarea de obiecte

– invocarea de obiecte prin intermediul IDL.

Suplimentar, BOA furnizeaza un suport minimal pentru securitate. Un obiect poate invoca operatia get_principal(), care va returna o referire la un serviciu de autentificare care este responsabil pentru invocarea curenta. Autentificarea în sine si detaliile control al accesului nu sunt specificate în OMG. Asa cum definitiile interfetei sunt stocate în depozitul interfetei, implementarile pentru BOA se asteapta a fi stocate într-un depozit de implementari. Un depozit de implementari tipic poate stoca programe compilate, scripte partajate pentru a starta si a initializa obiecte. Una dintre sarcinile mari ale BOA este aceea de a activa un obiect. Activarea unui obiect are loc în doua faze. În prima faza,BOA activeaza implementarea, ceea ce, în mod uzual înseamna startarea programului care contine obiectul. Un program poate contine mai multe obiecte, ceea ce conduce la situatia în care în faza a doua BOA sa activeze un obiect particular care este solicitat. Politica de activare a BOA descrie modul în care un obiect poate fi mapat pe un proces. OMG pretinde ca BOA sa accepte patru astfel de politici:

– activarea numai a unui singur obiect pe proces

– activarea mai multor obiecte pe proces

– rularea unui nou proces pentru a executa fiecare operatie

– permisivitatea ca o entitate din afara BOA sa activeze obiectul

Cu toate ca CORBA specifica detaliile numai pentru BOA , anumite medii pot contine mai mult adaptoare obiect. În consecinta, OMG include detalii asupra modului în care un obiect îsi poate selecta propriul adaptor obiect pe parcursul initializarii sale.

1.3 Serviciile CORBA

Serviciile CORBA sunt partea de jos a facilitatilor CORBA.Serviciile sunt fundamentele care suporta interactiuni comune intre obiecte.Serviciile sunt definite in specificatia OMG Common Services Specification(COSS).Maniera in care ar putea fi implementate nu este definita in model dar tipurile de interfete sunt.Ne putem gandii la servicii ca la o marire si complementare a functionalitatii unui ORB.Le folosesc pentru a crea o componenta,pentru numirea ei sau introducerea ei in mediul de subordonare la ORB.OMG a publicat standarde pentru un set de cincisprezece servicii.

Iata care sunt serviciile curente:

Servicii CORBA Definitii

Dintre toate aceste servicii in cadrul aplicatiei va fi folosite serviciul de numire(Name Service) si serviciul de interogare(aflare) al interfetelor obiectelor(Interface Repository).

1.4 Facilitatile CORBA

Facilitatile CORBA sunt partea superioara a serviciilor CORBA.Aceasta este zona pentru dezvoltarea software a ambelor tipuri de facilitati: orizontale si verticale.Facilitatile orizontale pot fi descompuse in patru tipuri:

• Managementul informatiei

• Managementul sistemelor

• Managementul sarcinilor

• Interfata utilizator

Managementul informatiei se concentreaza pe structura informatiei.Aceste facilitati includ:

• Metodologia pentru schimbul de date (information interchange)

• Stocarea datelor (data encoding and representation)

• Structurarea datelor (information modeling)

• Structurarea bazelor de date (information storage and retrieval)

Managementul sistemelor se concentreaza pe structura administrativa.Aceste faciltati includ:

• Metodologia de lucru cu colectiile (data collection, collection management)

• Structura pentru controlul accesului (policy management)

• Structura pentru managementul evenimentelor (event management)

• Structura pentru asocierile intre obiecte (instance management)

• Structura pentru managementul extensiilor obiectelor (customization)

• Managementul securitatii (security)

• Structura pentru selectarea serviciilor (quality of service management)

• Metodologie pentru analiza sistemului (instrumentation)

• Structura pentru managementul timpului (scheduling management)

Facilitatile verticale definesc necesitati unice in cadrul unei anumite piete de desfacere.Unele dintre pietele care au propriile definitii CORBA sunt:contabilitatea, manufacturierea, grafica, exploatarea petrolului si diferite forme de simulare.Cateva exemple de facilitati CORBA pentru retele sunt:

• Procesarea datelor

• Serviciile financiare

• Posta

• Printarea

1.5 Conceptele legate de Limbajul de definire al interfetelor (IDL)

Limbajul de definire al interfetelor(IDL) descrie interfetele pe care obiectele client le apeleaza iar implementarea obiectelor le furnizeaza.O interfata IDL defineste in intregime o interfata pentru un obiect si specifica parametrii fiecarei operatii.Conceptele IDL sunt mapate intr-un numar de limabaje precum Java,C++ si SmallTalk.IDL respecta regulile lexicale din C++.Gramatica sa este un subset al standardului Ansii C++

Proiectarea unei aplicatii CORBA.O aplicatie CORBA este creata folosind limbajul IDL.Aceasta necesita minimum definirea interfetelor pentru obiect si crearea a doua interfete IDL una pentru client si alta pentru server.De retinut faptul ca serverul si clientul sunt obiecte si nu reprezinta intocmai notiunile din modelul client/server.Conform CORBA un server este un obiect care este accesat in timp ce un client este un obiect care acceseaza un alt obiect.Astfel daca un obiect este accesibil si acceseaza alte obiecte in acelasi timp poate fi vazut si ca client si ca server.Exista un principiu primar in ceea ce priveste IDL si anume ca IDL se foloseste pentru definirea interfetelor si nu este folosit pentru implementarea aplicatiilor.Acest principiu asigura independenta fata de limbajul de programare folosit in implementarea clientului sau a serverului.Un server poate fi scris in Java iar clientul poate fi scris in C++.Aceasta sustine o caracteristica de baza a arhitecturii CORBA si anume portabilitatea ca fiind capabilitatea de a rula pe diferite platforme.Definitiile IDL pot fi comparate cu definitiile de interfete din Java sau cu un fisier header din C++.Este vorba de o descriere a interfetei si nu de o implementare.

1.6 Cum este independenta de limbaj dobandita?

Conceptul de mapare pentru un limbaj este utilizat aici.Maparea pentru un limbaj este procesul care specifica o constructie IDL printr-o constructie dintr-un alt limbaj.OMG a dezvoltat o serie de mapari pentru limbaje precum Java,C,C++ si COBOL.Acest lucru este important deoarece intr-o anumita retea pot exista o varietate de limbaje de programare si sisteme de operare.Aceasta mapare furnizeaza deasemenea 7si libertatea de a alege limbajul de programare dorit pentru oricare aplicatie in parte.

Procesul crearii unei interfete IDL pentru Server

Principalii pasi sunt:

1. Definirea interfetei IDL pentru server.

2. Implementarea folosind fie abordarea de tip delegare sau cea de tip mostenire.

Compilarea codului pentru a genera cioturile pentru client(client stubs, folosite ca o reprezentare locala pentru interfata unui obiect necesara pentru transmiterea parametrilor si receptionarea rezultatului ) si scheletoanele pentru server(server skeletons,necesarea pentru a lucra efectiv cu implementarea obiectului).

4. Implementarea interfetei IDL pentru server presupune definirea metodelor din interfete

5. Compilarea aplicatiei de pe server ce defineste metodele din interfata.

6. Rularea aplicatiei server.

7. Repetarea pasilor anteriori in caz ca pasul 6 nu a avut succes.

Procesul crearii unei interfete IDL pentru Client

Principalii pasi sunt:

1. Utilizarea cioturilor client generate in compilarea originala.

Legarea clientului la un obiect server.

3.Utilizarea interfetelor ale obiectului server

1.7 Probleme de proiectare

Arhitectura CORBA este complexa;la fel este insa si cea client/server.Exista o diferenta semnificativa intre teorie si practica in cazul CORBA.Modelul client/server clasic este format in principiu din trei parti:clientul,serverul si tot ceea ce se afla intre ele,iar in plus in momentul de fata mai este impartit si pe straturi.In contrast CORBA este o lume a obiectelor cu fiecare obiect situat intr-o lume statica definita de functia principala a obiectului.Proiectarea sistemului trateaza in primul rand infrastuctura mostenita.

Marile obiective ale proiectarii sunt interoperabilitatea,portabilitatea si consistenta.Dupa proiectarea infrastructurii o problema secundara ar fi daca mediul permite mai multe fire de executie simultan.Aici problema multi-fir ridica problema accesului concurent la obiecte.O consideratie importanta este aceea ca un server CORBA in orice moment de timp poate avea mai multi care incearca accesul.Cu un singur fir de executie,serverul preoceseaza un singur client odata,acest lucru avand un impact major asupra performantei sistemelui.

1.8 Interfata petru invocare dinamica

Interfata petru invocare dinamica(Dinamic Invocation Interface) face posibila urmatoarele lucruri:

• Ingaduie unui client sa acceseze servicii fara a fi nevoie de existenta cioturilor client(client stub) pentru acele servicii.

• Ingaduie unui client CORBA sa gaseasca (descopere) dinamic o interfata.

• Invoca o metoda pe un obiect pentru a implementa o interfata.

Observatie:DII se aplica numai pe partea de client.

DII nu este o cerinta absolut necesara pentru proiectarea unui sistem CORBA insa exista cel putin doua tipuri de aplicatii unde utilizarea DII ar putea fi un beneficiu foarte mare acela ca aplicatia gaseste obiectele si le apeleaza.Aplicatiile posibile sunt un browser generic de obiecte asa cum se vrea si aplicatia dezvoltata in lucrare si o unealta pentru proiectare.

Cea mai simpla forma de browser de obiect este o unealta pentru testare.Ar asista in gasirea obiectelor din retea si interfetele lor si invocarea de metode din interfata cu un set de parametrii de test.Cu un grad foarte mare de imaginatie un foarte sofisticat Web browser ar putea fi dezvoltat.O alta aplicatii a DII-ului este crearea unei unelte pentru proiectarea aplicatiilor CORBA adica ceva asemanator cu utilizarea limbajului UML pentru a genera direct cod.Unealta ar putea fi folosita pentru gasirea interfetelor CORBA existente si generarea de cod client care sa utilizeze obiectele asociate interfetelor.

1.9 Interoperabilitatea

Unul dintre scopurile principale ale CORBA este de a asigura interoperabilitatea dintre diferite ORB-uri,astfel ca un client dintr-un ORB poate invoca obiecte din diferite ORB-uri. Specificatia interoperabilitatii CORBA suporta obiecte pe retele distribuite care sunt administrate de multipli,heterogeni brokeri de acces(ORB) care respecta specificatia de baza CORBA.Exista cateva concepte care pun baza interoperabilitatii CORBA.Acestea includ protocoale,domenii si punti.Protocoalele sunt baza pentru dezvoltarea puntilor.Cele trei tipuri de protocoale sunt:

• Protocoale Generale inter-ORB (GIOP)

• Protocoale Internet inter-ORB (IIOP)

• Protocoale inter-ORB specifice mediului (ESIOP)

Aceasta permite programatorilor de a construi aplicatii are utilizeaza obiecte care ruleaza pe diferite ORB-uri, produse de mai multi furnizori. Abordarea din CORBA 2.0 este bazata pe un protocol de comunicatie comun care poate fi utilizat pentru comunicare cu obiecte care lucreaza pe diferite ORB-uri. Acest protocol este numit GIOP (General Inter-ORB Protocol), iar maparea acestuia pe TCP -ul Internet este IIOP (Internet Inter -ORB Protocol). GIOP specifica o reprezentare comuna a datelor, precum si mesajele si formatele acestor mesaje care pot fi transmise între client si server (obiect receptor al cererii) ORB. GIOP specifica, de asemenea, un numar de cerinte pentru protocolul de transport; acestea includ: livrarea fiabila ‘at-most-once- a datelor, nereordonarea datelor si suportul pentru fragmentare. Anumite ORB-uri vor fi capabile sa sustina IIOP ca un protocol nativ, fie ca este singurul protocol pe care acestea îl utilizeaza pentru comunicare, fie ca poate sustine stive de protocoale multiple simultan. Cea de a doua abordare necesita ca ORB sa cunoasca pentru un mesaj dat ce protocol utilizeaza, realizând astfel comunicarea cu obiectele dintr-un alt ORB prin utilizarea IIOP. Din pacate nu toate ORB-urile sunt capabile sa accepte IIOP ca protocol nativ. Pentru astfel de ORB-uri, OMG a specificat o alta abordare a interoperabilitatii si anume bridge-urile.

Un bridge este o aplicatie care permite obiectelor care utilizeaza un ORB de a comunica cu obiecte care utilizeaza alt ORB, chiar daca cele doua ORB-uri nu utilizeaza acelasi protocol. Daca unul dinte ORB-uri nu accepta IIOP ca protocol nativ interoperabilitatea se va realiza prin furnizarea asa numitului ‘half-bridge’ ce se manifesta între protocolul sau intern si IIOP.

Sa consideram de exemplu interoperarea a doua ORB care utilizeaza ‘half-bridge’ pentru IIOP (cele doua ‘half-bridge’lucreaza împreuna pentru a forma un ‘bridge’ complet). Cele doua obiecte care utilizeaza ORB-uri diferite sunt considerate ca fiind în domenii diferite. Trebuie remarcat faptul ca ‘bridge’ –urile din exemplu utilizeaza DII (interfata invocarii dinamice) si acesteia îi corespunde pe partea de server DSI (interfata structurii dinamice). Aceasta din cauza ca ‘bridge’–ul este generic; poate fi utilizat pentru a invoca orice obiect indiferent ce interfata are acel obiect. ‘Bridge’ –ul poate fi construit si utilizând canalele si structurile IDL, dar în acest caz acesta nu poate fi utilizat pentru orice obiect, exceptie facând acele canale care sunt încorporate în ‘bridge’. În consecinta, adaugarea de obiecte noi în cele doua domenii din exemplu, va fi necesara adaugarea a unei perechi noi de ‘bridge’ pentru a le face accesibile în alte domenii. Utilizarea DII si DIS evita aceasta complicatie.

Problemele se complica, aparând dificultati noi, pentru necesitatea maparii diferitelor reprezentari ale referintelor obiectelor care sunt trecute ca parametru sau returnate ca rezultat. De aceea, se impune ca toate ORB-urile conforme cu CORBA sa accepte IIOP fie ca protocol nativ, fie prin furnizarea unui ‘half-bridge’ la IIOP. ORB-urile pot astfel interopera cu alte platforme obiect, putând fi astfel utilizate ca vehicul al integrarii sistemelor

.

1.10 Protocoale pentru asigurarea interoperabilitatii

Un protocol GIOP specifica sintaxa pentru trasferul standard de mesaje intre diferite ORB-uri.Ideea in spatele protocolului GIOP este faptul ca acest protocol este simpla,scalabil si usor de implementat.Un protocol GIOP care ruleaza pe diferite tipuri de transport nu sunt implicit interoperabile.

Un protocol IIOP specifica schimbul de mesaje GIOP in cadrul(peste) conexiunile TCP/IP.Acesta este protocolul standard pentru conectivitatea pe Internet.IIOP poate fi utilizat doar int-un mediu TCP/IP intrucat cu celelalte protocoale pot exista probleme de interoperabilitate.

Protocolul de tip ESIOP specifica o interoperabilitate standard pentru o infrastructura locala de retea distribuita.Aceasta este un lucru important pentru functiile specializate cum ar fi administrarea si securitatea.

Un domeniu este un set de obiecte care au caracteristici comune si adera la reguli comune.Cateva exemple de domenii sunt:

• Managementul

• Adresarea in retea

• Conectivitatea in retea

• Securitatea

• Tranzactia

Un domeniu poate face parte dintr-un alt domeniu sau doua domenii pot fi legate.Teoria multimilor poate fi un concept bun pentru asemanarea cu domeniile si felul in care ele se combina.

Puntile CORBA sunt niste concepte care se refera la functionalitatea maparii intre diverse domenii.Exista doua tipuri de punti:punti immediate si punti mediate.Aceste tipuri vor determina elementele relevante de interactiune intre domenii.

1.11 Mai mult de un ORB

Intre granitele unui singur domeniu este relativ usor sa faci ca ORB-urile sa vorbesca intre ele.Este insa un mecanism mai complex pentru interoperabilitate atunci cand se incearca comunicarea cu un ORB dintr-un alt domeniu si de accea trebuie definit un alt mecanism.Spre exemplu se poate definii siguranta in termeni de domenii,am putea avea domenii de securitate joasa,medie si inalta la fel ca si pentru domeniile internet.Aceasta este insa abordarea din interiorul organizatiilor complexe.In abordarea clasica exista de obicei foarte putina interactiune intre diferite domenii.Aceasta inseamna ca intre granitele unui singur domeniu un utilizator are un singur cont pentru conectare.IIOP este protocolul care pune baza interoperabilitatii CORBA.Daca un ORB suporta protocolul IIOP atunci poate comunica transparent cu alte ORB-uri.Prin extensie, orice serviciu care este implementat de ORB-ul ce respecta specificatia CORBA poate fi utilizat de un alt ORB.Deci este posibil sa mixam si sa oferim serviciile intre multiple domenii.In ultima faza puntile fac posibil sa utilizam referinte obiect dintr-un domeniu intr-un alt domeniu.Aceast lucru este indeplinit prin definirea unui model de informatie concis pentru referintele la obiecte ,model cunoscut sub denumirea de Interoperable Object References(IOR).

1.12 Referinte la obiecte interoperabile(IOR)

Urmatorul tip de informatie este continut in cadrul unui stream IIOP:

• Referinta nula – evident, referintele nule nu pot avea invocatii efectuate asupra lor

• Defineste in mod neambiguu tipul referintei obiect . IOR -urile au nevoie sa contina informatie despre tipurile de referinta la obiect pentru ca diferite implementari ale acestui model de obiect CORBA sa le poata trata intr-o maniera consistenta. Acest lucru ofera reprezentare uniforma a modelului pentru un obiect in cadrul a diferite platfome pentru ORB-uri si limbaje de programare.

• Suportul pentru protocol – IOR-urile incapsuleaza informatie despre protocol astfel ca destinatarul IOR-ului sa aleaga cel mai eficient protocol care este disponibil

• Serviciile disponibile ale ORB-ului – daca o referinta obiect foloseste diverse servicii CORBA pentru a facilita invocarea,aceasta informatie este incapsulata in IOR.Acest lucru este necesar in primul rand pentru a asista negocierea pentru obtierea unei interfete la serviciile care folosesc un format standard(cele care au fost prezentate in cadrul acestu capitol).Aceasta inseamna ca un client poate retrage referinte obiect la servicii in mod neambiguu.

Putem crea referinte IOR din referinte la obiecte.Aceste referinte sunt cunoscute ca referinte obiect de tip sir(stringified object references).Aceste referinte pot fi transmise la un client care necesita serviciile unei componente a serverului.Pe partea de client,aceste referinte tip sir pot fi convertite inapoi in referinte obiect si astfel permitand ca operatiile sa fie invocate asupra lor.API-il necesar pentru aceste operatii se gaseste in clasa ORB.Mai exact se folosesc doua operatii ORB::object_to_string si ORB::sring_to_object care realizeaza conversia unei referinte obiect intr-un IOR si invers.

Capitolul 2

Obtinerea de Referinte si Interfete ale Obiectelor

2.1 Serviciul de Nume(Name Service)

Serviciul de nume(Name Service) este cel mai folositor serviciu,el oferind posibilitatea ca o aplicatie sa localizeze un obiect prin nume.Poate fi vazut deci ca o carte “Paginii Aurii” insa pentru obiectele CORBA distribuite.Aceasta utilitate este binevenita in cazul in care aplicatia ar putea avea cateva sute de obiecte raspandite intre mai multe gazde.

În serviciul de numire numele sunt tratate ca pseudo-obiecte. Aceasta înseamna ca limbajul de constructie permite programatorilor de a manevra numele ca obiecte CORBA ordinare. Cu toate acestea nu este o cerinta expresa ca acestea sa fie implementate ca si obiecte CORBA; implementarile se vor realiza tinând cont de criterii de eficienta. Aceasta are avant ajul de a masca reprezentarea interna a numelor. Contextele sunt obiecte ordinare CORBA si pot fi limitate la numele dintr-un context, exact ca si alte obiecte. Serviciul de numire defineste interfata contextului care contin operatiile:

– legarea unui obiect cu un nume în context

– stergerea unei legaturi dintre un obiect si un nume din context

– legarea unui nou context cu un nume, în contextul curent

– rezolvarea unui nume la un obiect dat (referinta)

Se propune standardizarea unei interfete de comert ca parte a COS. O astfel de interfata va permite clientilor sa specifice restrictii relative la valorile unor proprietati arbitrare pentru un serviciu la care se doreste legarea. Acesta va returna clientului unul sau mai multe referinte ale obiectelor care sunt asociate acestuia si care satisfac restrictiile proprietatilor enuntate. Acest serviciu apare cert ca si un serviciu de brokeraj.

2.2 De ce sa folosim Serviciul de Nume

Trebuie tinut cont de faptul ca obiectele distribuite isi pot muta virtual locatia oricand.Prin virtual se intelege ca numele gazdei s-ar putea schimba sau ar putea muta serviciile de la o gazda la alta gazda si asa mai departe.Serviciul de Nume face ca locatia obiectului sa fie transparenta clientului.Atata timp cat obiectele sunt inregistrate cu Serviciul de Nume clientul va putea intodeauna sa le gaseasca.In mod esential un server(sau un client care se comporta ca un server reprezentant pentru un alt server) poate lega un nume la un obiect.Partile interesate in obtinerea referintei la obiecte cunocute prin nume pot rezolva numele prin rezolvare intelegand obtinerea referintei la obiect.In mod ideal Serviciul de Nume mentine nume doar pentru referintele la obiectele importante., restul obiectelor fiind transmise ca argumente ale operatiilor acest lucru marind viteza comunicatiei.

2.3 Ce este un nume?

In specificatia standard modulul COSNaming identifica un nume folosind structura Name Component:

struct NameComponent{

string id;

string kind;

};

Numele unei componente este retinut in atributul NameComponent.id.Acesta este numele care este utilizat pentru a gasii un nume.Atributul NameComponent.id este folositor si in oferirea de informatie auxiliara in legatura cu componenta insasi.De la aceasta structura nu mai este decat un pas pentu a definii un nume:

typedef sequence <NameComponent> Name;

Acest procedeu va permite unei aplicatii sa formeze un sir de legaturi NameComponent pentru a crea un nume.Spre exemplu o companie aeriana are un numar de hangare raspandite in lume.Pentru simplitate voi considera ca Serviciul de Nume este disponibil doar hangarelor din U.S..In aceasta tara compania are patru hangare in Los Angeles,New York,Chicago si Denver.Avioanele sunt mutate constant de la un hangar la altul.Aceasta necesita ca clientul sa detina mai multe referinte obiect ana la fiecare hangar pentru a putea opera cu hangarele si deci a afla si avioanele.

Organizarea unei ierarhii de numire implica un lucru numit Context de Numire(Naming Context).Un Context de Numire suporta o organizare a numelor.Numele serverului (NameServer) este radacina Context-ului de Numire.

2.4 Crearea contextelor

Anumite aplicatii folosesc Naming Context-ul pentru a lega numele intr-o structura ordonata asemenea structurii de fisiere de pe un sistem de operare.Exista doua procedee de creare a unui context:

NamingContext new_context();

NamingContext bind_new_context(in Name name)..;

Prima operatie ofera posibilitatea crearii unui NamingContext.Operatia bind_context este apoi apelata pentru a atasa un context la un nume(ceva asemanator cu a da un nume unui fisier/director creat in interiorul altui director).Urmatoarea operatie bind_new_context creaza un nou context de numire si-l leaga la un nume.

Exista doua operatii pentru legarea numelor la Naming Service:

void bind(in Name name, in Object object) raises (NotFound, CannotProceed,

InvalidName, AlreadyBound)

void bind_context(in Name name, in NamingContext context) raises (NotFound,

CannotProceed, InvalidName, AlreadyBound)

Un Serviciu de Nume poate fi folosit pentru a organiza aplicatiile CORBA.Aceast lucru este indeplinit prin permiterea ca aplicatiile sa creeze mai intai un NamingContext si apoi sa lege numele la un context particular.Operatia bind_context permite legarea unui nume la un NamingContext.Operatia bind permite legarea unei referinte obiect cu o legatura(asociere nume context).Este posibila folosirea unui nume compus pentru a face acest lucru astfel ca doar ultimul nume din secventa va corespunde cu numele componentei.

Observatie:Numele trebuie sa fie unice intr-un context de numire.Daca un nume este deja utilizat atunci se va arunca exceptia AlreadyBound.

Operatiile:

void rebind(in Name name, in Object object) raises (NotFound, CannotProceed,

InvalidName, AlreadyBound)

void rebind_context(in Name name, in NamingContext context) raises (NotFound,

CannotProceed, InvalidName, AlreadyBound)

fac posibil atasamentul unei noi referinte obiect la un nume.Operatia rebind_context face acelasi lucru cu exceptia ca NamingContext-ul este schimbat prin numele dat ca parametru.Vechiile legaturi sunt pierdute prin executarea acestor operatii.

2.5 Stergerea Contextelor si Numelor

Daca un nume trebuie sa fie sters,urmatorul apel poate fi facut asupra Serviciului de Nume:

unbind(in Name name)…

Un nume complet valabil va fi stfel sters din Contextul de Numire la care era atasat.Pentru a sterge un NamingContext gol se foloseste operatia:

void destroy()…

care va arunca o exceptie NotEmpty daca exista nume care sunt inca atasate la context.Daca exista astfel de nume vor fi sterse prin functia unbind(…).

2.6 Rezolvarea Numelor

Operatia resolve() ar trebuii invocata asupra Serviciului de Nume daca o referinta obiect trebuie sa fie dobandita de client.Operatiile folosite sunt:

Object resolve(in Name name) raises (NotFound, CannotProceed, InvalidName);

Trebuie retinut faptul ca un obiect CORBA (CORBA::Object) este returnat.O metoda narrow()(ingustare sau cast) este executata asupra obiectului generic pentru a duce referinta obiect in tipul dorit.

2.7 Metadate in CORBA

Pentru a respecta specificatia CORBA fiecare componenta care o scriem trebuie sa se contina un mecanism prin care se autodescrie.Fiecare obiect la nivel de sistem si serviciu care locuiesc pe magistrala CORBA trebuie deasemenea sa poata sa se autodescrie. Chiar si magistrala CORBA se poate autodescrie.Ca rezultat intreg sistemul CORBA se poate autodescrie in termenii de interfete.

Limbajul IDL este limbajul de reprezentare a metadatelor in CORBA.Depozitarul metadatelor CORBA este Depozitarul de Interfete(Interface Repository) care nu este altceva decat o baza de date existenta la executie care contine specificaiile de interfete ale fiecarui obiect pe care ORB-ul il recunoaste.Ne putem gandii la IR ca si la o baza de date interogabila si modificabila care exista doar in timpul executiei ORB-ului si contine informatia generata de limbajul IDL.

Precompilatorul IDL si Depozitarul de Interfete sunt servicii de baza al ORB-ului si sunt livrate in oricare implementare de ORB ce respecta specificatia CORBA.Cu toate acestea ORB-ul implementat in platforma Java 1.4.2 nu are o implementare pentru Interface Repository ci doar api-uri pentru a comunica cu IR-ul unui alt ORB.

2.8 Rolul limbajului IDL in oferirea interoperabilitatii

IDL limbajul de reprezentare a metadatelor este un limbaj contractural care ne permite sa specificam granitele componentelor si interfetele lor cu potentialii clienti.Limbajul CORBA IDL este neutru si total declarativ.Aceasta inseamna ca nu defineste detaliile de implementare.Limbajul IDL ofera independenta interfete independente fata de sistemul de operare si limbajul de programare la toate serviciile si componentele care rezida pe o magistrala CORBA.

2.9 Contractul IDL

Un contract IDL include o descriere a oricarei resurse sau serviciu pe care o componenta a serverului vrea sa o expuna clientilor sai.Componentele serverului trebuie sa suporte doua tipuri de clienti:

1)clienti la executie care invoca serviciile lor

2)programatori care folosesc limbajul IDL pentru a extinde functiile componentelor prin mostenire.

In ambele cazuri limbajul IDL este necesar pentru a specifica interfetele componentelor astfel ca implementarea sa poata fi tratata ca o cutie neagra.

Putem folosii limbajul IDL pentru a specifica atributele unei componente (sau variabile publice) ,clasele parinte de la care mosteneste,exceptiile care le poate arunca.Gramatica limbajului IDL este un subset al limbajului C++ cu cuvinte cheie aditionale pentru a suporta conceptele distribuite si deasemenea suporta preprocesarea standard din C++.

Limbajul IDL este un limbaj descriptiv.Suporta sintaxa din C++ pentru constante,tipuri si declaratii de operatii.Totusi IDL nu include nici o structura procedurala sau variabila aceasta intrucat separa implementarea de specificatie si tot datorita acestei separari limbajul IDL este o unealta pentru notatie buna pentru arhitectii software.Majoritatea limbajelor notationale sau metalimbaje ofera doar descrieri ale interfetelor.In contrast limbajul CORBA IDL ofera o cale directa intre o arhitectura software(definita prin interfetele sale) si codul compilat care o implementeaza.

Folosind descrierile IDL un precompilator poate direct genera cioturile pentru client si implementarea scheletului pentru server.Limbajul IDL ofera deasemenea o cale de a incapsula API-urile de nivel jos in cod software care poate fi folosit de programator.

2.10 Structura limbajului CORBA IDL

Depozitarul de interfete(Interface Repository) contine metadate care sunt identice cu componentele care le descriem in IDL.De fapt Depozitarul de Interfete este o baza de date simpla care contine versiuni compilate ale metadatelor capturate via IDL(prin compilarea contractului IDL si incarcarea interfetei in acest depozitar de interfete) asa ca trebuie mai intai sa cunoastem structura limbajul IDL.

Elementele de baza care constituie limbajul CORBA IDL:

Modulele care ofera un spatiu de numire(asemanatoare cu package-urile din JAVA)pentru a grupa un set de descrieri de clase.Un modul este identificat prin cuvantul cheie module.Un modul are un nume(sir de caractere) pentru numirea spatiului care il acopera.

Interfetele definesc un set de metode(sau operatii) pe care un client le poate invoca asupra unui obiect.Ne putem gandii la ele ca si la niste definitii de clase dar fara sectiunea de implementare.O interfata poate declara una sau mai multe exceptii care indica daca operatia a fost executata cu succes.O interfata poate avea atribute.Acestea sunt valori pentru care implementarea creaza automat operatii de tip get si set.Putem declara ca un atribut sa fie read-only,caz in care implementarea ofera doar functia get.O interfata poate fi derivata din una sau mai multe interfete,ceea ce inseamna ca IDL suporta mostenirea multipla de interfete.Sintaxa pentru mostenirea este aceeasi ca-n C++.

Operatia este echivalentul CORBA al unei metode.Denota un serviciu pe care clientii pot sa-l invoce.Fisierul IDL defineste semnatura operatiei adica parametrii metodelor precum si tipul rezultatului intors de metoda.Un parametru are un mod(mode) care indica daca valoarea este trimisa de la client la server(in),de la server la client(out) sau trimisa de client pentru a fi modificata de server si apoi a fi intoarsa de server(inout).Parametrul are deasemenea si un tip care constrange valorile pe care le poate lua.Imediat in fata metodei trebuie sa apara tipul rezultatului intors de metoda.Semnatura metodei poate definii si exceptiile pe care o metoda le poate arunca atunci cand detecteaza o eroare.

Tipurile de data sunt utilizate in descrierea valorilor acceptate de parametrii,atribute,exceptii si valori returnate.Aceste tipuri de date sunt numite obiecte CORBA care acopera multiple limbaje,sisteme de operare si ORB-uri.Corba accepta doua categorii de tipuri:tipuri de baza si tipuri compuse.Tipurile de baza CORBA includ short,long,unsigned long,unsigned short,float,double,char,boolean si octet.Tipurile compuse contin enum,string,struct,array,union,sequence si any.Tipul struct este similar cu cel din C++.Tipul sequence ne permite sa transmitem un tablou de dimensiune variabila de obiecte,dar trebuie totusi specificat numarul maxim de obiecte care pot fi plasate intr-un sequence.Tipul any este foarte util in situatii dinamice deoarece poate reprezenta orice tip IDL de baza sau compus sau referinte la obiect.Aceasta inseamna ca putem folosii any pentru a transmite orice tip de informatie.Fiecare tip IDL este mapat intr-un tip de data nativ limbajului de programare folosit pentru implementarea sereverului sau a clientului folosind mapari limbaj corespunzatoare.

2.11 Un exemplu de interfata specificata in limbajul IDL

Voi definii doua interfete CORBA una numita Caine iar cealata Pisica intr-un modul numit Animale:

module Animale

{ /*definitia pentru interfata Caine */

interface Caine:Domesticit,Animal

{

attribute integer varsta;

exception Neinteresat {string explicatie};

void latra(in short cat_de_mult) raises (Neinteresat);

void aseazate(in string unde) raises (Neinteresat);

void maraie(in string la_semnal) raises (Neinteresat);

}

interface Pisica:Animal

{

void mananca();

void vinoAici();

}

} /*sfarsit modul */

Dupa cum se observa interfata Caine mosteneste metodele si atributele interfetelor Domesticit si Animal.Deasemenea atributul varsta pentru interfata Caine va oferii pe parte de server metodele pentru setarea si obtinerea varstei.Evident cele trei metode pot sau nu avea succes in a se efectua corect insa aceasta depinde de faptul daca cainele este sau nu interesat deci pot arunca o exceptie de tip Neinteresat daca cainele ne este interesat in a efectua comenzile date.

2.12 Type Code-uri CORBA (Date autodescriptive)

CORBA defineste type code-uri care reprezinta fiecare tip IDL definit.Folosim aceste type code-uri pentru a crea date autodescriptive care pot fi transmise intre diferite sisteme de operare,ORB-uri si Depozitare de Interfete.Fiecare type code are un numar unic global de identificare in cadrul Depozitarului de Interfete.Type code-urile sunt folosite de exemplu de catre:

Interfetele de Invocare Dinamica(DII) pentru a indica tipurile de data ale diverselor argumente

Protocoalele Inter-ORB-uri incluzand IIOP si ESIOP pentru a specifica tipurile de data ale argumentelor din cadrul mesajelor care sunt transmise intre ORB-uri si sisteme de operare.

Depozitarul de Interfete pentru a crea descrieri IDL neutre fata de ORB

Tipul de data any pentru a oferii un mod de autodescriere a unui parametru generic.

Interfata TypeCode din CORBA defineste un set de metode care ne permit sa operam asupra type code-urilor,sa le comparam si sa obtinem descrierile lor

2.13 Depozitarul de Interfete(Interface Repository)

CORBA suporta in Depozitarul de Interfete nu numai interfetele locale ci si interfete ale unor obiecte gazduite de alte ORB-uri prin acest lucru se asigura autonomie pentru administratorii locali ai ORB-urilor care au doar interfetele in Depozitarul local.Incepand cu versiunea CORBA 2.0 aceasta facilitate pentru Interface Repository este posibila prin:

1)introducerea unui set de metode noi pentru modificarea incrementala a continutului unui Interface Repository in timpul executiei

3)introducerea identificatorilor globali unici pentru interfetele din Interface Repository care pot fi folositi intr-un spatiu de nume distribuit.

Interface Repository este o baza de date on-line ce contine definitii de obiecte.Putem captura aceste definitii direct dintr-un compilator IDL sau prin intermediul functiilor de scriere a definitiilor intr-un Interface Repository.Specificatia CORBA nu specifica cum aceste definitii pot ajunge aici insa specifica cum este organizata informatia si chestionata(citita).Acest lucru se face prin intermediul unor clase ale caror instante reprezinta informatia care se afla in Interface Repository.

Rezultatul acestei organizari este o foarte flexibila baza de date de obiecte care tine evidenta colectiilor de obiecte.Desigur toate obiectele din depozitar sunt versiuni compilate ale informatiei care exista intr-un fisier IDL.

2.14 De ce este nevoie de un Depozitar de Interfete

Un ORB are nevoie sa inteleaga definitiile obiectelor cu care lucreaza.O cale pentru a obtine aceste definitii este prin incorporarea informatiei in cioturile client.Cealalta cale de a obtine aceasta informatie este printr-un Interface Repository accesibil in mod dinamic.Ce face un ORB cu informatia din depozitar?Raspunsul consta in faptul ca poate face mai multe lucruri cu acele definii de obiecte si anume:

Poate oferii o verificare a tipurilor parametrilor din semnaturile metodelor.Tipurile parametrilor sunt verificate indeferent daca cererea a fost trimisa folosind API-urile pentru invocari dinamice sau printr-un stub(adica invocare statica pentru ca interfata este cunoscuta).Semnaturile definesc parametrii unei metode si tipul lor

Poate ajuta ORB-urile sa se inter-conecteze.Un Interface Repository format din definitii de obiecte rezidente pe ORB-uri diferite este folosit pentru a translata obiecte pe ORB-uri heterogene.Trebuie folosit acelasi identificator din depozitar pentru a descrie aceste obiecte.

Poate oferii metadate clientilor si uneltelor.Clientii folosesc Interface Repository pentru a crea invocari dinamice.Unelte precum browsere de clase,generatori de aplicatie si compilatoare pot folosii aceasta informatie pentru a obtine ierarhii de mostenire si definitii de clase in timpul executiei.

Poate oferii obiecte autodescriptive adica putem apela metoda get_interface asupra oricaru-i obiect CORBA pentru ai obtine informatia legata de interfata sa(binenteles dupa ce aceasta informatie a fost publicata in Interface Repository)

Interface Repository-urile pot fi mentinute local sau pot fi administrate ca resurse departamentale(distribuite).Servesc ca resurse de valoare cu metainformatie despre structuri de date si interfete ale componentelor.Un ORB poate avea acces la mai multe Interface Repository.

2.15 Implementare

Interface Repository este implementat ca un set de obiecte care reprezinta informatie.Aceste obiecte trebuie sa fie persistente ceea ce inseamna ca trebuie stocate pe un mediu nonvolatil.CORBA grupeaza metadatele in module care reprezinta spatii de nume.Numele din depozitar sunt unice in cadrul unui modul.CORBA defineste o interfata pentru fiecare din cele opt structuri IDL ale sale:

ModuleDef defineste o grupare logica de interfete.Ca si un fisier IDL ,Depozitarul de Interfete foloseste modulele pentru a grupa interfetele si pentru a naviga in cadrul grupurilor folosind un nume.Deci ne putem gandii la un modul ca si la un spatiu de nume.

InterfaceDef defineste interfata obiectelor; contine lista de constante,typedef-uri ,exceptii si definitiile de interfete.

OperationDef defineste o metoda din interfeta unui obiect,contine lista de parametrii si exceptii aruncate de aceasta operatie.

ParameterDef defineste un argument al unei metode.

AttributeDef defineste un atribut al interfetei.

ConstantDef defineste o constanta.

ExceptionDef defineste exceptiile care pot fi aruncate de catre operatie.

TypeDef defineste tipurile numite care fac parte dintr-o definitie IDL

Pe langa aceste opt interfete care reprezinta structuri IDL,CORBA specifica o interfata pentru Depozitar care serveste ca radacina pentru toate modulele continute intr-un spatiu de nume din Depozitar.Fiecare Interface Repository este reprezentat de catre un obiect depozitar de tip radacina.Figura urmatoare arata ierarhia claselor folosite:

Figura 1.2

Arhitectii CORBA au observat aceste ierarhii si apoi au definit trei superclase abstracte care nu pot fi instantiate numite IRObject,Container si Contained.Toate obiectele de tip Interface Repository mostenesc interfata IRObject.Aceasta interfata ofera o operatie pentru identificarea tipului actual al unui obiect, cat si o operatie de distrugere.Obiectele care sunt containere mostenesc operatii de la interfata Container.

Interfata Contained defineste comportamentul obiectelor continute in alte obiecte.Toate clasele de tip depozitar sunt derivate din una din interfetele Container,Contained sau amandoua odata prin intermediul mostenirii multiple.Aceasta schema de ierarhie ofera posibilitatea obiectele de tip depozitar de a se comporta conform relatiilor de apartenenta in ierarhie.Interfata Contained ofera operatia move pentru a muta un obiect din Container-ul sau curent in altul.Relatiile de mostenire sun ilustrate prin urmatoarea figura:

Figura 2.2

Putem accesa metadatele din Interface Repository prin invocarea metodelor polimorfic asupra diferitor obiecte.Datorita acestui design putem naviga si extrage informatia din obiectele din depozitar folosind doar noua metode.Cinci dintre acestea sunt derivate din clasele parinte Container si Contained.Celelalte patru metode sunt specifice lui InterfaceDef si Repository.Iata o descriere a metodelor de citire si de navigare:

Describe:atunci cand invocam aceasta metoda asupra unui obiect tinta de tip Contained va returna o structura de descriere continand informatia de tip DL care descrie acel obiect

Lookup:atunci cand invocam aceasta metoda asupra obiectelor de tip Container va returna o secventa de pointeri la obiectele pe care le contine.

Lookup_name:este invocata asupra unui obiect de tip Container pentru a localiza un obiect continut in Container prin numele sau.

Contents:se invoca asupra obiectelor de tip Container si returneaza o lista a obiectelor direct continute sau mostenite de acest obiect.Putem folosii aceasta metoda pentru a naviga in cadrul unei ierarhii de obiecte.De exemplu pot incepe cu un obiect de tip Repository si apoi sa listez obiectele care le contine si asa mai departe.

Describe_contents:se apeleaza asupra unui obiect de tip Container si returneaza o secventa de pointeri la descrierile continutului obiectelor pe care le contine.Aceasta metoda combina metodele contents si describe.Putem limita spatiul de cautare prin excluderea obiectelor mostenite sau prin cautarea unui tip specific de obiect(spre exemplu de tipul InterfaceDef)

Describe_interface se apeleaza asupra unui obiect de tip InterfaceDef si intoarce o structura care descrie in intregime acea interfata incluzand numele sau,identificatorul din Interface Repository,numarul versiunii,operatii,atribute si toate interfetele parinte.

Is_a e apelata asupra unui obiect de tip InterfaceDef si intoarce TRUE daca interfata este identica sau mosteneste direct de la interfata care este specificata in parametrul functiei.

Lookup_id se apeleaza asupra unui obiect de tip Repository pentru a obtine o referinta la un obiect primitiv.Acesta inseamna un obiect nemutabil care este detinut de catre depozitar.Exemple de obiecte nemutabile include referintele de obiecte,tipuri de baza si type code-uri.

Impreuna aceste metode ne permit sa navigam in cadrul unui Interface Repository.Putem cauta in spatiile de nume sau module specifice dupa obiecte care indeplinesc un anumit criteriu de cautare.Atunci cand gasim un obiect il folosim pentru a descrie metodele pentru a retrage informatia IDL care il defineste.Deasemenea nu trebuie uitat ca IRObject,Container si Contained sunt clase abstracte ceea ce inseamna ca nu va trebuii sa lucram cu ele niciodata in mod direct.In schimb insa vom invoca metode asupra obiectelor din Interface Repository care isi mostenesc comportamentul de la aceste clase de baza.

2.16 Cum gasesc o interfata

Pot gasii interfata unui obiect in trei feluri:

Prin apelarea directa a metodei Obiect::get_interface.Pot adresa aceasta invocare asupra oricarei referinte de obiect valide.Apelul va intoarce un obiect de tip InterfaceDef care descrie in totalitate interfata obiectului.Aceasta metoda este folositoare atunci cand intalnesc un obiect al carui tip nu il cunosc in timpul compilarii.

Prin navigarea prin spatiu de nume de tip modul folosind o secventa de nume.De exemplu daca stiu numele interfetei pe care doresc sa o gasesc pot incepe cautand-o in modulul radacina al depozitarului.Atunci cand gasesc un rezultat apelez metoda InterfaceDef::describe_interface pentru a obtine metadatele de care am nevoie si care descriu acea interfata.

Prin localizarea obiectului de tip InterfaceDef care corespunde cu un identificator(ID) pentru Interface Repository.Pentru a face acest lucru apelez metoda Repository::lookup_id.

Odata obtinuta interfata unui obiect printr-un obiect InterfaceDef pot invoca metode asupra interfetei pentru a gasii metadatele de care am nevoie.Pot folosii aceste metadate pentru a invoca dinamic metode asupra acelui obiect.

2.17 Interfete ce apartin diferitor ORB-uri

Interface Repository-urile pot opera peste mai multe ORB-uri.Pentru a evita insa problemele de numire aceste depozitare vor asigna identificatori unici(Interface Repository IDs) interfetelor si operatiilor globale.

Putem folosii acesti Repository ID pentru a creea copii ale metadatelor in cadrul mai multor Interface Repository si in acelasi timp sa asigur o vedere coerenta asupra lor.Aceasta inseamna ca numarul unic de indentificare al unei interfete este rezervat in afara granitelor unui ORB.De exemplu cu un identificator de interfete pot obtine cateva metadate despre o interfata dintr-un depozitar local.Pot apoi obtine restul metadatelor asupra aceleiasi interfete dintr-un depozitar indepartat.

Pentru a asigura faptul ca definitiile IDL din diverse depozitare nu contin duplicate,CORBA defineste urmatoarele conventii de numire:

nume de domenii care identifica in mod unic module,interfete,constante,typedef-uri,exceptii,atribute,operatii si parametrii in cadrul unui Interface Repository.Un nume de domeniu consta din doi sau mai multi identificatori separati prin caracterele “::”.

Numere de indentificare in cadrul Depozitarului de Interfete identifica global module,constante,typedef-uri,exceptii,atribute,operatii si parametrii.Sunt folosite pentru sincroniza si a asigura consistenta definitiilor intre diferiti brokeri sau depozite de interfete.

Un numar de identificare in cadrul depozitarului de interfete este un sir de caractere format dintr-o ierarhie de numire cu trei nivele.CORBA 2.0 defineste doua formate pentru specificarea ID-urilor globale(ce pot fi cunoscute si altor ORB-uri):

Folosind numele IDL cu prefixe unice.Pot crea un RepositoryID folosind un nume IDL care consta din trei componente separate de “:”.Prima componenta este sirul “IDL”, a doua componenta este o lista de identificatori separati prin caraterul “/” iar a treia component e formata din numere de versiune in format zecimal separate de cate un punct.De exemplu un identificator valid pentru interfata Pisica in modulul Animale este “IDL:/CainePisicaOrganizatie/Animale/Pisica/:1.0.In acest caz CainePisicaOrganizatie este un prefix unic care denota o organizatie.Pot folosii deasemenea un ID de tip Internet pentru un pefix(sau oricare alt nume unic).

Folosind Identificatorii Universali Unici de tip DCE(UUID).DCE ofera un genrator UUID care calculeaza un numar global unic folosind data curenta ,timpul,ID-ul unei placi de retea si un numarator de frecventa ridicata.Nu exista aproape nici o sansa ca acest algoritm sa creeze UUID-uri duplicate.Formatul DCE pentru identificatori consta deasemenea si din trei componente separate de “:”.Prima componenta este sirul “DCE”.A doua componenta este UUID-ul iar a treia componenta este formata dintr-un numar de versiune si un format zecimal.De exemplu un identificator DCE pentru depozitar ar putea arata astfel: “DCE:700dc500-0111022ce-aa9f:1”.

Pot asocia identificatori pentru Interface Repository odata cu definitia IDL in mai multe moduri.De exemplu o unealta instalata le poate genera sau un precompilator IDL ii poate genera pe baza unei directive “pragma” pe care o include in fisierul IDL.

Directiva aceasta spune precompilatorului IDL cum sa genereze identificatori si cum sa-I asocieze cu o interfata particulara.CORBA 2.0 defineste trei metode de creare a identificatorilor folosind directiva ‘pragma’:

Directiva “prefix pragma” seteaza un prefix care va fi aplicat la toti identificatorii de interfete IDL ce urmeaza pana la intalnirea unei alte directive “pragma”.Formatul acestei directive este “#pragma prefix <string>” .Un exemplu este: #pragma prefix “CainePisicaOrganizatie”.

Directiva “version pragma” adauga un numar de versiune la sfarsitul identificatorului unui nume IDL specific.Formatul este #pragma version <name> <major> <minor>.Fara un pragma versiunea 1.0 este implicit adaugata.Exemplu: #pragma version Pisica 1.3.

Directiva “ID pragma” asociaza un identificator arbitrar unui nume IDL.Formatul acestei directive este :#pragma ID <name> <id>.Un exemplu este: #pragma ID Pisica “DCE:700dc500-0111-22ce-aa9f:1”

Capitolul 3

Interfata pentru Invocare Dinamica

3.1 Libertatea oferita de invocarile dinamice

Intr-o lume client/server, Interfata pentru Invocare Dinamica(DII) este cel mai apropriat lucru de libertatea absoluta crescand considerabil nivelul de interoperabilitate intre client si server.

DII furnizeaza clienti cu alternativa de a utiliza canale IDL la invocarea unui obiect. DII este uzuala pentru anumite aplicatii specializate cum ar fi bridge-urile si browser-ele. S-a anticipat ca multi clienti CORBA vor utiliza canale IDL. Un obiect care primeste o cerere nu poate conchide care din cele doua mecanisme vor fi utilizate de catre client. Asa cum s-a prezentat deja canalele IDL permit clientului sa utilizez aceiasi sintaxa la invocarea la distanta ca si la invocarea locala.

Utilizarea DII implica clientul într-o suma de pasi suplimentari. Într-un anume sens, mecanismul DII este mai putin abstract ca si canalul IDL. Acesta mascheaza mai putine aspecte ale distributiei decât canalul IDL,

solicitând o cantitate de munca mai mare pentru programatori. Cu toate acestea sunt clase de aplicatii pentru care utilizarea DII este mai eficienta. Una dintre aceste clase de aplicatii sunt browser-ele.

Într-o abordare cu utilizarea canalului IDL pentru invocare browser -ul trebuie reconstruit pentru a încorpora un canal IDL pentru fiecare noua clasa care este adaugata bibliotecii. Prin utilizarea DII se poate baleia orice clasa fara a fi necesara încorporarea de canale IDLL atragerea facilitatilor comune apare necesitate utilizarii DII pentru a construi bridge -uri si gate-uri între diferite ORB. În schimb, noile versiuni al CORBA au inclus facilitatile corespunzatoare pentru servere, interfete structura dinamica, specifica astfel încât bridge-urile pot fi sustinute.

DII sunt suport pentru invocari asincrone si invocari multiple asincrone.

Interfata pentru invocare dinamica(Dynamic Invocation Interface) permite unui client sa aleaga orice obiect tinta in timpul executiei si apoi sa invoce dinamic metode asupra lui.Clientul poate astfel invoca orice operatie asupra oricarui obiect fara sa fie nevoie sa compileze fisierul IDL adica fara sa cunoasca interfata obiectului.

Aceasta inseamna ca clientul descopera informatia leagata de interfete in timpul executiei(run-time) fara sa aiba nevoie de cunostiintele din timpul compilarii.Server-ele ofera servicii noi si interfete oricand ele devin disponibile.

Clientii vor descoperii aceste interfete in timpul executiei si vor sti cum sa le apeleze.Totul face parte din atuurile tehnologiei CORBA.

DII ofera un mediu dinamic care permite sistemelor sa ramana flexibile si extensibile.Aceasta este o caracteristica de dorit mai ales in mediile inter-continentale asa cum este Internetul.

Dar cum descopera clientul aceste obiecte la distanta?Raspunsul este multiplu.

Cea mai simpla abordare este aceea in care se furnizeaza clientului o referinta obiect de forma sir de caractere(stringified object referecnce).

Clientul poate convertii sirul intr-o referinta obiect completa si apoi poate face conexiunea.

Deasemenea clientul poate cauta obiectele dupa nume folosind Serviciul de Numire din CORBA.

O alta modalitate este cea prin care descopera aceste obiecte folosind Serviciul Trader din CORBA(descris in capitolul 1) care joaca rolul Paginilor Aurii pentru CORBA putand alege intre obiecte dupa serviciile(operatiile) pe care le ofera.

Intr-un mediu orientat obiect,obiectele vor fi dinamic descoperite de catre mici programe denumite spiders,crawlers,bots(vezi GoogleBot),motoare de cautare,servicii de tip portal,publicare sau inscriere si agenti de toate tipurile.

Odata ce clientii descopera aceste obiecte vor avea nevoie de DII pentru a invoca operatiile lor.Alternativa ar fi sa descarci un applet Java cu un client preconstruit pentru un serviciu particular.

Pentru server nu conteaza daca clientii lui il apeleaza folosind invocarea dinamica sau cioturile client obtinute in urma compilarii fisierului IDL.Deci pentru a suporta invocarea dinamica serverul nu trebuie sa suporte nimic special.

3.2 Pasii

Inainte de a invoca dinamic o metoda asupra unui obiect,trebuie mai intai sa gasim obiectul si sa obtinem referinta sa.Odata ce am gasit referinta la obiect o putem folosii pentru a obtine interfata obiectului si apoi sa construim in mod dinamic o cerere.Trebuie insa sa specificam in cerere metoda care dorim sa o executam si parametrii sai.

In mod tipic obtinem aceasta informatie de la un Interface Repository.Deasemenea un Serviciu Trader poate marii functiile IR.Spre exemplu un server poate specifica un interval de valori pe care le asteapta.

Sa presupunem acum ca am obtinut o referinta la obiect printr-unul din mijloacele mai sus prezentate.Iata in continuare care sunt principalii pasi efectuati in invocarea metodei asupra obiectului:

Obtinerea numelui interfetei.In cazul nostru avem o referinta pentru obiectul server.Obiectele CORBA sunt introspective in sensul ca ne pot oferii informatie despre ele insele.In mod consecvent putem cere unui obiect numele interfetei sale invocand asupra obiectului metoda get_interface.Acest apel intoarce o referinta la un obiect de tip InterfaceDef.Acesta este un obiect in interiorul unui Interface Repository care descrie aceasta interfata.

Obtinerea descrierii metodei din Interface Repository.Putem folosii InterfaceDef ca un punct de plecare pentru navigarea in cadrul Interface Repository.Putem obtine toate tipurile de informatie detaliata cu privire la interfata si metodele pe care le suporta.CORBA specifica in jur de zece apeluri pentru navigarea in cadrul unui Interface Repository si descrierea obiectelor pe care le contine aceasta.Metodele folosite sunt lookup_name pentru a gasii metoda pe care dorim sa o invocam,apoi folosim metoda describe pentru a obtine intreaga definitie a metodei sau putem adresa prin metoda describe_interface o cerere pentru descrierea intregii interfete si gasirea metodei care dorim sa o invocam.

Crearea listei cu argumente.CORBA specifica o structura de date autodescriptiva pentru transmiterea parametrilor,care se numeste Named Value Lista(lista cu valori numite/descrise).Implementam aceasta lista invocand metoda create_list si adaugand prin metoda add_item atati parametrii cat sunt nevoie adaugandu-i astfel in lista Named Value.In mod alternativ putem lasa ORB-ul sa creeze o lista pentru noi invocand metoda create_operation_list asupra unui obiect CORBA::ORB.Trebuie sa-i transmitem numele operatiei pentru care returneaza o lista.

Crearea cererii.O cerere CORBA este un pseudo-obiect care contine numele metodei,lista de argumente si valoarea intoarsa de metoda.Putem crea o cerere invocand metoda create_request.Trebuie sa–i transmit numele metodei care vreau sa o invoc,obiectul NVList,si un pointer spre tipul returnat.In mod alternativ pot crea o versiune scurta o cererii invocand metoda _request si transmitandu-i doar numele metodei care doresc sa o apelez.Folosim varianta scurta pentru apelul metodelor care nu au parametrii.

Invocarea cererii.Putem efectua(invoca) cererea in unul dintre urmatoarele trei moduri:

apelul metodei invoke trimite cererea si obtine rezultatele

prin apelul metodei send_deferred care intoarce imediat controlul programului care mai apoi va trebuii la un moment dat in cadrul programului sa se intoarca dupa rezultate folosind metodele poll_response sau get_response

trimiterea apelului poate fi definita ca nefiind nevoie de un raspuns inapoi in acest caz folosindu-se metoda send_oneway.

Aceste trei stiluri de invocare sunt cunoscute sub denumirea de sincrone,sincrone cu intarziere si one-way(intr-un singur sens).

Dupa cum se observa se cere putin efort pentru a invoca dinamic o metoda.Actualmente invocarea metodei este usoara insa partea mai dificila este construirea cererii.Aceasta constructie este si mai dificila intrucat sunt mai multe moduri de a coonstruii si de a invoca metoda la distanta.

3.3 Interfetele de Invocare Dinamica

Serviciile pe care trebuie sa le invoc dinamic fac parte din miezul arhitecturii CORBA.Aceste metode sunt dispersate intre patru interfete din modulul CORBA.Iata o vedere de ansamblu a acestor patru interfete care se folosesc pentru invocarea dinamica:

CORBA::Object este o interfata pseudo-obiect care defineste operatiile pe care fiecare obiect CORBA trebuie sa le suporte.Este interfata de baza pentru toate obiectele CORBA.Aceasta interfata include trei metode pe care le folosim pentru a construii invocari dinamice.Apelam metoda get_interface pentru a obtine interfata pe care obiectul o suporta.Apelul intoarce o referinta la un obiect InterfaceDef care este un obiect aflat in interiorul lui Interface Repository care descrie aceasta interfata.Putem apela create_request pentru a crea un obiect de tip Request(cerere) caruia trebuie sa-i transmitem numele metodei si parametrii pentru invocarea la distanta.Sau putem crea o versiune scurta a obiectului cerere apeland metoda _request careia ii transmitem doar numele metodei care dorim sa o apelam la distanta.

CORBA::Request este o interfata pseudo-obiect care defineste operatiile asupra unui obiect la distanta.Metoda add_arg adauga in mod incremental(unul dupa altul) parametrii pentru cerere.Metoda invoke efectueaza o invocare/intoarcere de rezultat.Metoda send_deffered intoarce controlul programului nostru dupa transmiterea cererii.Invocam poll_response pentru a gasii daca cumva s-a returnat un mesaj(pentru valoarea intoarsa).Apoi invocam get_response pentru a citii mesajul.Putem trimite un apel in sens unic prin invocarea metodei send_oneway.Apoi la sfarsit invocam metoda delete pentru a sterge obiectul Request din memorie.

CORBA::NVList este o interfata pseudo-obiect care ajuta in construirea listei de parametrii ai metodei ce urmeaza a fi apelata dinamic.Un obiect NVList contine o lista de structuri de date autodescriptive numite NamedValues.Iata codul IDL care defineste aceasta structura:

Struct NamedValue

{ Identifier name; //numele argumentului

any argument; //argumentul

long len; //lungimea valorii argumentului

Flags arg_modes; //in,out,or,inout

Interfata NVList defineste operatii care ne lasa sa manipulam o lista.Invocam metoda add_item pentru a adauga un parametru listei.Putem seta valoarea sa invocand metoda add_value.Prin apelarea get_count obtinem numarul total de itemuri alocate pentru lista.Putem sterge un item din lista prin invocarea metodei remove.Pot invoca free_memory pentru a golii orice asociatie de memorie cu lista alocata dinamic .Si apoi invoc free pentru a elibera insasi structura de lista.Acest ultim apel va apela si free_memory in numele nostru.

CORBA::ORB este o interfata la un pseudo-obiect care defineste metodele ORB de uz general.Putem invoca aceste metode asupra unui pseudo-obiect ORB fie din implementarea de pe partea de client fie de pe partea de server.Sase dintre aceste metode sunt specifice constructiei unei cereri dinamice.Apelam create_list pentru a crea o lista(pseudo-obiect) NVList goala pe care va trebuii sa o populez.Daca vrem ca ORB-ul sa faca aceasta sarcina in locul nostru vom apela metoda create_operation .Aceasta metoda va crea o lista NVList si o va popula automat cu descrierile argumentelor pentu operatia la distanta pe care o specific.ORB-ul oferapatru operatii pentru trimiterea si receptionarea cererilor multiple.Apelam send_multiple_requests_oneway pentru a trimite multiple cereri in sens unic.Apelam send_multiple_requests_deferred pentru a trimite mai multe cereri care asteapta si raspuns.Pentru a ne intoarce dupa raspunsuri vom apela poll_next_response si apoi cu metoda get_next_response pentru a citii urmatorul mesaj.

Pe langa aceste patru interfete folosim deasemenea si obiecte Interface Repository pentru a contrui invocarea dinamica la distanta.

3.4 Scenarii pentru invocarea dinamica

Intrucat folosirea a asa de multe interfete poate fi dificila voi prezenta in continuare trei metode de apelare dinamica.

Prima varianta e considerata ca fiind metoda in care parcurgem fiecare pas elementar fara a grupa laolalta mai multi pasi.Dupa cum s-a specificat crearea unei cereri este partea cea mai dificila din invocarea dinamica.In aceasta varianta voi construii cererea fara ajutorul ORB’ului.Iata o descriere pas cu pas:

Chestionez obiectul pentru ai afla interfata sa aflata in Interface Repository.Pentru a face acest lucru folosim invocam metoda get_interface asupra oricarui obiect CORBA obtinand un obiect de tip InterfaceDef care descrie in totalitate aceasta interfata.

Caut metoda de care sunt interesat.Apelez metoda lookup_name asupra obiectului de tip InterfaceDef obtinut pentru a obtine un obiect de tip OperationDef care descrie in totalitate metoda pe care doresc sa o apelez in mod dinamic.

Obtin descrierea metodei.Apelez metoda describe asupra obiectului de tip OperationDef pentru a obtine o descriere integrala a metodei.

Creez o lista de tip NVList goala.Apelez metoda create_list asupra obiectului de tip ORB pentru a crea o lista goala de tip NVList.Trebuie sa specific si numarul de item-uri pe care trebuie sa-le aloc pentru lista.

Popularea listei NVList.Apelam metodele add_item si add_value pentru fiecare argument din metoda.

Cream obiectul de tip cerere.Acest lucru se face apeland metoda create_request asupra referintei la obiect si creaza un obiect de tip Request.Trebuie sa-i transmit: 1)numele metodei 2)lista NVList 3)o data de tip autodescriptiv NamedValue pentru a receptiona rezultatul.

Invocarea operatiei la distanta.Apelez invoke pentru a apela metoda asupra obiectului la distanta.Aceasta este o invocare sincrona.Rezultatul va apare in obiectul de tip Request.

Eliberez obiectul cerere.Apelez delete pentru a sterge obiectul de tip Request.

Eliberez lista de argumente NVList.Apelez free pentru a sterge spatiul asociat cu aceasta lista.

Dupa cum se vede este necesar de putin efort pentru crearea in mod dinamic a unei cereri.In urmatoarea varianta vom lasa ORB-ul sa efectueze cativa pasi in locul nostru.

Varianta a doua este mai usoara intrucat vom lasa ORB-ul sa asambleze descrierile de parametrii in locul nostru.Iata acum o descriere pas cu pas a interactiunilor:

Chestionez obiectul in legatura cu definitia interfetei sale.Putem invoca metoda get_interface asupra oricarui obiect CORBA pentru a obtine un obiect de tip InterfaceDef care descrie in totalitate interfata obiectului aflata in Interface Repository.

Caut metoda de care sunt interesat.Apelam lookup_name asupra obiectului InterfaceDef pentru a obtine un obiect de tip OperationDef care descrie in toatalitate metoda pe care vreau sa o apelez in mod dinamic.

Cerem ORB-ului sa creeze si sa populeze o lista de argumente NVList.Apelam apoi create_operation_list pentru a lasa ORB-ul sa creeze o lista de argumente NVList pe care o populeaza cu numele si tipurile de data ale argumentelor.Pentru aceasta va trebuii sa-i transmitem ca parametru obiectul OperationDef.

Setarea valorilor pentru argumente.Acest lucru se realizeaza apeland add_value pentru a seta valoarea fiecarui argument in lista de argumente NVList.

Creez un obiect cerere.Apelez metoda create_request asupra referintei obiectului pentru a crea un obiect de tip Request.Trebuie sa-i transmit: 1)numele metodei 2)lista de argumente NVList 3)o data de tip autodescriptiv NamedValue pentru a receptiona rezultatul.

Invocarea metodei.Se foloseste invoke pentru a apela metoda pentru obiectul la distanta.Aceasta efectueaza o cerere sincrona iar rezultatul va aparea in obiectul Request.

Eliberez obiectul cerere.Apelez delete pentru a sterge obiectul de tip Request.

Eliberez lista de argumente NVList.Apelez free pentru a sterge spatiul asociat cu aceasta lista.

Dupa cum se observa chiar si ajutorul ORB-ului nu simplifica destul de mult munca depusa in construirea cererii si apelarea dinamica.

A treia varianta este asemanatoare cu prima in anumite privinte.Insa in loc sa adaug argumente unei liste NVList le voi adauga obiectului de tip Request.Astfel voi crea un obiect Request gol pentru o operatie.Apoi il voi popula treptat cu argumente.Iata o descriere a pasilor urmati:

Chestionez obiectul pentru ai afla interfata sa aflata in Interface Repository.Pentru a face acest lucru folosim invocam metoda get_interface asupra oricarui obiect CORBA obtinand un obiect de tip InterfaceDef care descrie in totalitate aceasta interfata.

Caut metoda de care sunt interesat.Apelez metoda lookup_name asupra obiectului de tip InterfaceDef obtinut pentru a obtine un obiect de tip OperationDef care descrie in totalitate metoda pe care doresc sa o apelez in mod dinamic.

Obtin descrierea metodei.Apelez metoda describe asupra obiectului de tip OperationDef pentru a obtine o descriere integrala a metodei.

Cream obiectul de tip cerere.Acest lucru se face apeland metoda create_request asupra referintei la obiect si creaza un obiect de tip Request.Trebuie sa-i transmit numele metodei pe care vreau sa o invoc.

Popularea cu argumente a obiectului cerere.Voi apela add_arg si add_value pentru fiecare parametru pe care metoda il asteapta.

Invocarea operatiei la distanta.Apelez invoke pentru a apela metoda asupra obiectului la distanta.Aceasta este o invocare sincrona.Rezultatul va apare in obiectul de tip Request.

Eliberez obiectul cerere.Apelez delete pentru a sterge obiectul de tip Request

Aceasta ultima varianta poate fi foarte folositoare in anumite situatii.De exemplu atunci cand o metoda pe care o apelez nu preia nici un parametru, astfel creez obiectul request si apoi il invoc asupra obiectului.

Capitolul 4

Aplicatia Client Grafic CORBA

4.1 Structura generala

Aplicatia trateaza realizarea unui client grafic pentru CORBA.

Specificatia CORBA respectata de aplicatie este CORBA 2.3.

Aplicatia a fost creata folosind limbajul Java2,platforma 1.4. si ca software pentru brokerul de obiecte s-a folosit Java ORB care este inclus in aceasta platforma nefiind astfel nevoie de prezenta de software strain platformei Java2.

Doresc sa mentionez faptul ca brokerul de acces la obiecte Java ORB nu implementeaza un Interface Repository care are rolul in gestionarea interfetelor obiectelor ale caror servicii brokerul le poate intermedia(oferii).

Clientul grafic trebuie sa fie capabil sa adreseze invocari dinamice asupra oricarui obiect care rezida pe server ,este publicat in Name Service in sensul ca exista o asociere nume in Name Service – aplicatie(servant) locala si pentru acest obiect se cunoaste fisierul IDL care descrie in termenii limbjului IDL interfata obiectului care urmeaza a fi apelat.

In mod normal pentru a apela metode asupra unui client trebuie compilata interfata sa adica fisierul IDL.In cazul de fata desi se compileaza si fisierul IDL codul rezultat nu este folosit de client sub nici o forma(clientul nu conoaste acest cod) acest lucru fiind de altfel si esenta Invocarii Dinamice si anume aceea ca clientul nu cunoste in momentul compilarii nici o informatie despre obiectul server pe care il apeleaza.

Aplicatia pe partea de client sau clientul grafic este impartita in patru parti de baza corespunzatoare a patru clase Java.Din cele patru clase Java clasele Corba ce contine fereastra grafica principala si conectarea si clasa Extragere sunt cod propriu in timp ce la clasa care listeaza NameService-ul contributia adusa este de jumatate in scrierea codului.La partea de invocare dinamica contributia mea consta in localizarea unui obiect in cadrul unui context in Name Service si intoarcerea unei referinte.

Intre cele patru clase de baza nu exista relatii de mostenire sau de delegare.

Aceasta se datoreaza faptului ca cele patru calse nu au caracteristici comune si nu e nevoie de stocarea nici unei referinte intr-o clasa spre o instanta a alteia aceasta intrucat aplicatia nu are nevoie decat de un singur obiect din fiecare tip si deci nefiind necesara prezenta de constructori pentru a instantia obiecte cu caracteristici diferite. Din aceasta cauza comunicarea intre clasele de baza se face folosind membrii statici ai claselor aplicatiei cu observatia ca clasa care le aduna laolalta pe celelate clase de baza este clasa Corba.Pentru o descriere generala a curgerii informatiei intre clase se va privi figura urmatoare si doresc sa mentionez ca sagetile cu doua varfuri sau cu un singur varf nu au rol de notare a relatiilor de mostenire ci indica clasa de la care provine informatie:

Figura 1.4

Pe langa cele patru clase mai exista o serie de clase interioare fara nume care implementeaza tratarea de evenimente asociate diferitelor butoane fie ele din fereastra principala sau din ferestre secundare.

Deasemenea sunt prezente si clase neinterioare asa cum sunt cele din fisierul Extragere.java care joaca un rol de depozitare pentru informatiile extrase.

Ordinea in care vor fi parcurse meniurile este cea indicata si de fereastra principala si care presupune pe rand efectuarea de operatii din clasele Corba.

Logica desfasurarii operatiilor poate fi dedusa din figura urmatoare:

Figura 2.4

4.2 Implemetare

Pricipala functie a clientului este adresarea de apelari asupra unui obiect server.

In functie de obiectul ales si interfata acestuia functiile apelate variaza.

Inainte insa de incepe discutia trebuie trecut in revista modul de implementare al obiectului de servant publicat pe server.

Sa luam un exemplu simplu in care servantul are urmatoarea interfata specificata in termenii limbajului IDL:

Fisierul ceva.idl

module Exemplu

{

interface Operatii

{

long afis(in string s);

float raport(in long i, in long j);

};

};

Dupa cum se observa aceasta descriere in pseudo-limbajul IDL ofera destula informatie despre servant.Si anume stim ca acesta implementeaza o interfata numita Operatii.

In cadrul acesteia el va oferii acces la doua functii una numita afis iar celalta raport.De observat ca nu exista nici o specificare a modului de implementare a acestor functii in acest fisier acesta de altfel fiind si rolul pricipal al limbajului IDL acela de a separa implementarea de interfata asigurand astfel independenta aplicatiei client fata de aplicatia server.

Se observa ca sunt indicate tipurile parametrilor pe care ii asteapta cele doua functii precum si tipurile rezultatelor intoarse de cele doua functii.

Presupunand ca suntem acum inca pe partea de server vom compila acest fisier folosind compilatorul idlj care mapeaza codul IDL in cod Java:

>idlj –fserver ceva.idl

Pasul urmator tot pe partea de server este lansarea in executie a brokerului de acces la obiecte pe un anumit port si folosindu-ne pe post de IP gazda 127.0.0.1 sau localhost avand in vedere ca ORB-ul serverului ruleaza local.

>orbd –ORBInitialPort 1049 –ORBInitialHost localhost

Figura 3.4

Daca totul a decurs corect ORB-ul va rula acum ca serviciu si va trebuii sa ramana rezident in memorie iar promptul din care a fost lansat se va bloca(va ramane in asteptare) ,”orbd” vine de la ORB Daemon (va furniza servicii altor aplicatii).

Pentru a oprii ORBD-ul tastam Ctrl+C.

Urmeaza acum compilarea servantului care implementeaza un obiect ce se va publica pe server si inregistrarea acestuia cu serverul(adica publicarea acestuia in Name Service).

In cadrul acestui servant va fi implementat codul pentru semnaturile functiilor prezente in fisierul ceva.idl.

Modul de implementare nu conteaza ceea ce conteaza insa este ca aceste functii sa respecte intocmai denumirea din fisierul idl,precum si ordinea si tipul argumentelor si tipul rezultatului intors.Iata codul care implementeaza functiile servantului si care leaga acest servant in contexte diferite si cu nume diferite acest lucru fiind un mod obisnuit de organizare sub forma de contexte a Name Service-ului.

class OperatiiImpl extends OperatiiPOA { //PUTEA FI SI SEPARAT

private ORB orb;

public void setORB(ORB orb_val) {

orb = orb_val;

}

// implementeaza metodele din interfata Operatii

public int afis(String s) {

//System.out.println("Sirul s este " + s);//Important: Se afiseaza pe masina serverului

return s.length();

}

public float raport(int i, int j) {

return (float)i/j;

}

}

public class Server {

public static void main(String args[]) {

try{

// crearea si initializarea ORB-ului

ORB orb = ORB.init(args, null);

// obtin o referinta la radacina adaptorului portabil de obiecte si activez POAManager

POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));

rootpoa.the_POAManager().activate();

// creez servant si-l inregistrez cu ORB-ul

OperatiiImpl operatiiImpl = new OperatiiImpl();

operatiiImpl.setORB(orb);

// obtin referinta obiectului de la servant

org.omg.CORBA.Object ref = rootpoa.servant_to_reference(operatiiImpl);

Operatii href = OperatiiHelper.narrow(ref);

// obtin o referinta la radacina contextului de numire(Name Service)

org.omg.CORBA.Object objRef =

orb.resolve_initial_references("NameService");

NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);

// leg referinte obiect sub diferite nume in cadrul Name Service-ului

String name = "Operatiile";

String name1 = "Director1";

String name2 = "Operatia1_1";

String name3 = "Operatia1_2";

String name4 = "Director2";

String name5 = "Operatia2_1";

String name6 = "Operatia2_2";

// Atentie!!

// Toate numele sunt legate la acelasi obiect

NameComponent path[] = ncRef.to_name( name );

ncRef.rebind(path, href);

NameComponent path1[] = ncRef.to_name( name1 );

NamingContextExt ctx2 = NamingContextExtHelper.narrow(ncRef.bind_new_context(path1));

System.out.println("New naming context, Director, added!");

NameComponent path2[] = ncRef.to_name( name2 );

ctx2.rebind(path2, href);

NameComponent path3[] = ncRef.to_name( name3 );

ctx2.rebind(path3, href);

NameComponent path4[] = ncRef.to_name( name4 );

NamingContextExt ctx3 = NamingContextExtHelper.narrow(ctx2.bind_new_context(path4));

System.out.println("New naming context, Director, added!");

NameComponent path5[] = ncRef.to_name( name5 );

ctx3.rebind(path5, href);

NameComponent path6[] = ncRef.to_name( name6 );

ctx3.rebind(path6, href);

System.out.println("Server ready and waiting …");

//astept invocatii de la clienti

orb.run();

}

catch (Exception e) {

System.err.println("ERROR: " + e);

e.printStackTrace(System.out);

}

System.out.println("Server Exiting …");

}

}

Dupa ce s-a compilat servantul acesta va fi inregistrat la server prin specificarea IP-ului si a gazdei pe care ruleaza orbd-ul.

La fel ca si la orbd acest prompt se va bloca si nu va trebuii sa fie inchis de utilizator:

>javac Server.java

>java Server –ORBInitialPort 1049 –ORBInitialHost localhost

Figura 4.4

Urmeaza acum partea de client executata la client ce presupune compilarea fisierului Corba.java ce va atrage dupa sine automat si compilarea celorlalte fisiere.Dupa acest pas se laseaza in executie byte-code-ul Corba.class:

>javac Corba.java

>java Corba

Figura 5.4

Din fereastra principala se vor parcurge pe rand cele patru meniuri:

Figura 6.4

Primul meniu efectueaza conectarea la server.Partea interesanta este ca nu mai trebuie sa rulez un orbd dintr-un prompt de comenzi ci el va fi lansat din intermediul aplicatiei grafice:

Figura 7.4

In dreptul IP-ului trebuie scris IP-ul gazdei unde ruleaza ORB-ul server-ului care in mod real nu ruleaza pe aceeasi masina ca in exemplu de fata unde noi specificam localhost sau 127.0.0.1.

Acest lucru se realizeaza prin urmatorul cod al handlerului asociat primului buton:

ActionListener handler=new ActionListener()

{ public void actionPerformed(ActionEvent e)

{

Corba.host=host.getText();

Corba.port=port.getText();

props.put("org.omg.CORBA.ORBInitialPort",Corba.port);

props.put("org.omg.CORBA.ORBInitialHost",Corba.host);

orb=ORB.init(args,props);

int sw=0; //initial nu a aparut nici o eroare

try{

objRef = orb.resolve_initial_references("NameService");

}

catch(org.omg.CORBA.SystemException e2) //arunca exceptia COMM_FAILURE daca nu reuseste conectarea

{ sw=1;

dialog(cadru,"Eroare:nu s-a putut efectua conectarea la ORB.\nDetalii:\n"+e2.toString());

//e2.printStackTrace(System.err);

}

catch(Exception e3) //tratarea pentru restul exceptiilor obisnuite

{

sw=1;

//e3.printStackTrace(System.err);

dialog(cadru,"Eroare de tip Exception:nu s-a putut efectua conectarea la ORB.\n Detalii:\n"+e3.getMessage());

}

if(sw==0) //Nu a survenit nici o eroare

{ d.dispose(); //inchid fereastra,eliberez resursele

dialog(cadru,"Detalii:\nConectarea a reusit!"); }

}

};//handler

Obs: se observa ca tratarea erorii se face pe incercarea de a obtine o referinta la Serviciu de Nume.Aceasta intrucat pe linia “orb=ORB.init(args,props);” nu apare eroare chiar daca portul sau host-ul sunt gresite.

Daca conectarea a reusit sau nu se afiseaza o fereastra dialog pentru afisarea status-ului daca conectarea a reusit sau nu.

Figura 7.4

Pentru urmatorul meniu pentru listarea Serviciului de Nume doresc sa adaug urmatoarele.In cadrul Serviciului de Nume pot exista contexte(de altfel si Name Service se retine tot intr-un context) asadar trebuie sa ne gandim la Serviciul de Nume ca si la sistemul de fisiere de pe un sistem de operare unde directoarele corespund contextelor iar fisierele corespund numelor de fisiere.

Functia care listeaza Serviciul de Nume este asadar o functie recursiva care parcurge in adancime fiecare director listand imediat dupa numele directorului si numele obiectelor publicate in cadrul sau.Iata codul functiei care realizeaza aceasta listare:

Clasa Nameserv:

static void recursiv(String sir,NamingContextExt nc, int k) //merge in adancime pe directoare

{

try

{

org.omg.CORBA.Object objRef1 = nc.resolve_str(sir);

NamingContextExt nc1 = NamingContextExtHelper.narrow(objRef1);

BindingListHolder bl1 = new BindingListHolder();

BindingIteratorHolder blIt1= new BindingIteratorHolder();

nc1.list(1000, bl1, blIt1);

Binding b[] = bl1.value;

for (int j=0; j < b.length; j++)

{

int lastIx1 = b[j].binding_name.length-1;

if (b[j].binding_type == BindingType.ncontext)

{

for (int ind = 0; ind<k; ind++) s=s+"_"; //System.out.print("-");

s=s+"Context: " + b[j].binding_name[lastIx1].id + "\n";

//System.out.println("Context: " + b[j].binding_name[lastIx1].id);

Nameserv.recursiv(b[j].binding_name[lastIx1].id, nc1,k+4);

}

else

{

for (int ind = 0; ind<k; ind++) s=s+"_"; //System.out.print("-");

s=s+"Obiectul: " + b[j].binding_name[lastIx1].id + "\n";

//System.out.println("Obiectul: " + b[j].binding_name[lastIx1].id);

}

} //for

}

catch(Exception e)

{

err=err + e.getMessage();

}

} //functia recursiv

De observat faptul ca se face un test la fiecare pas daca s-a ajuns la un context sau s-a ajuns la un nume de obiect.In cazul in care s-a ajuns la un context functia se autoapeleaza pentru a lista numele de obiecte publicate in noul context.

Figura 8.4

Meniul al treilea efectueaza extragerea din fisierul IDL a datelor despre tipurile prezente in fisier.

Pasii urmariti in extragere au fost:

separarea unitatilor lexicale in cuvinte si in punctuatie si stocarea lor intr-un obiect de tip Vector care are avantajul ca poate creste dinamic precum o stiva.

parcurgerea vectorului si nalizarea continutului

Iata spre exemplu analiza efectuata numai pentru extragerea tuturor datelor despre o functie:

//EXTRAGERE NUME FUNCTII ,PARAMETRII,INTERFETELE MAMA(primary key(nume_functie,nume_interfata))

for(i=0;i<v.size();i++)

//for(j=0;j<tipuri.size();j++) //adica daca gasim cumva un cuvant de tip poate e functie

//if ((v.elementAt(i).toString()).equalsIgnoreCase(tipuri.elementAt(j).toString())) //poate urma functie sau variabila

if(partOf(v.elementAt(i).toString(),tipuri)) //adica daca gasim cumva un cuvant de tip poate e functie

if((v.elementAt(i+2).toString()).equalsIgnoreCase("(") && !"raises".equalsIgnoreCase(v.elementAt(i+1).toString())) //super e functie

{ functii.nume.addElement(v.elementAt(i+1).toString()); //pe i+1 e numele functiei

String s1="";

if("unsigned".equalsIgnoreCase(v.elementAt(i-1).toString()) || "long".equalsIgnoreCase(v.elementAt(i-1).toString())) //adica poate este unsigned short

s1=v.elementAt(i-1).toString()+" "+v.elementAt(i).toString();

else

s1=v.elementAt(i).toString();

functii.tip.addElement(s1);

//si acum voi gasii si interfata parinte

for(int k=i-1;k>=0;k–) //merg in sus pt a o gasii

if((v.elementAt(k).toString()).equalsIgnoreCase("interface")) //am gasit-o

{ functii.interfata_parinte.addElement(v.elementAt(k+1).toString());

break; //corect break ciclu

}

//si voi gasii si parametrii metodei

functii.parametrii.addElement(""); //initial cred ca nu are nici un parametru

int k=i+3; //pe i+2 este (

while(!(v.elementAt(k).toString()).equalsIgnoreCase(")"))

{ String old=functii.parametrii.remove(functii.parametrii.size()-1).toString();

old=old+" "+v.elementAt(k).toString();

functii.parametrii.addElement(old);

k++;

}

}

sir=sir+"\nFUNCTII prezente:\n"; // System.out.println("\nFunctii prezente:");

listare2("Functie:",functii.nume," parametri:",functii.parametrii,"\n");

sir=sir+"\nTipurile functiilor:\n"; //System.out.println("\nTipurile functiilor:");

listare2("Functie:",functii.nume," tip:",functii.tip,"\n");

sir=sir+"\nApartenenta lor:\n"; //System.out.println("\nApartenenta lor:");

listare2("Functia:",functii.nume," in interfata:",functii.interfata_parinte,"\n");

Iesirea:

Figura 9.4

In final dupa ce s-au parcurs primele trei meniuri putem efectua invocari dinamice asupra obiectului pentru care avem atat referinta(pasul 2) cat si interfata(pasul 3).

Un lucru important este felul cum ajunge la obiect cererea in cazul in care obiectul face parte dintr-un context.

In acest caz se va obtine mai intai un context(NamingContextExt) relativ la contextul in care se afla publicat obiectul si abia apoi putem rezolva numele obiectului:

if (k == 0)

{

NamingContextExt nc = NamingContextExtHelper.narrow(Corba.objRef);

NameComponent nameComponent = new NameComponent(s, "");

NameComponent path[] = { nameComponent };

myServer = nc.resolve(path);

}

else

{

NamingContextExt namingContext = NamingContextExtHelper.narrow(Corba.objRef);

org.omg.CORBA.Object ob = namingContext.resolve_str(ss1);

NamingContextExt nc = NamingContextExtHelper.narrow(ob);

NameComponent nameComponent = new NameComponent(ss2, "");

NameComponent path[] = { nameComponent };

myServer = nc.resolve(path);

}

Figura 10.4

Afisarea rezultatului(lungimea sirului transmis intrucat s-a apelat metoda de calcul a lungimii unui sir):

Bibliografie

Figura 11.4

BIBLIOGRAFIE

BIBLIOGRAFIE

Similar Posts