Bazy danych i inżynieria oprogramowania

advertisement
Bazy danych i inżynieria oprogramowania
Wykład 4:
Wprowadzenie do
OMG CORBA
Kazimierz Subieta
Instytut Podstaw Informatyki PAN,
Warszawa
Polsko-Japońska Wyższa Szkoła
Technik Komputerowych, Warszawa
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 1
listopad 1999
Wołanie statyczne: krok po kroku (1)
interfejsy serwera (klasy obiektów) używając IDL. Interfejsy w
1 Zdefiniuj
IDL informują klienta o obiektach, które są w zasięgu ORB, o ich atrybutach, o
metodach, które wolno stosować, o parametrach i wyniku tych metod, oraz o
wyjątkach, które mogą być powodowane przez metody.
2 Wprowadź definicję interfejsu do repozytorium interfejsów, używając do tego
celu specjalnego udogodnienia. Informację tę mogą wykorzystywać programy
aplikacyjne np. dla celów wołań dynamicznych.
prekompilator do definicji interfejsów w IDL. Typowy prekompilator
3 Zastosuj
CORBA wyprowadza co najmniej trzy rodzaje kodu wyjściowego:
1) pniaki klienta dla metod zdefiniowanych w IDL. Pniaki te są używane
przez program klienta w celu statycznego dostępu do obiektów.
2) szkielety serwera, określające nagłówki metod (+ inne informacje), które
mają być zaimplementowane po stronie serwera.
3) Specyficzną dla danego języka programowania definicję klasy (np w Java
lub C++).
1) i 3) nie wymagają dalszych zabiegów, 3) musi być zapełnione kodem.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 2
listopad 1999
Wołanie statyczne: krok po kroku (2)
4Dodaj
kod po stronie serwera do szkieletu wyprodukowanego przez
wyrażenie IDL. Kod ten implementuje metody zdefiniowane w wyrażeniu IDL.
ten kod, używając w tym celu normalnego kompilatora wybranego
5 Skompiluj
języka programowania.
obiekty serwera w Repozytorium Implementacji. ORB używa tej
6Zarejestruj
informacji celem zlokalizowania aktywnych obiektów lub celem wykonania ich
aktywacji. Rejestracja obiektów wymaga napisania programu o dość
standardowej budowie.
instancje obiektów na serwerze. W czasie startu aplikacji, Adapter
7 Utwórz
Obiektów znajdujacy się na serwerze może tworzyć obiekty, które będą
obsługiwać odległe wołania metod ze strony klienta. CORBA definiuje
specjalne strategie Adaptera Obiektów, które są używane do tworzenia i
zarządzania tego rodzaju obiektami.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 3
listopad 1999
Wołanie statyczne: krok po kroku (3)
8Zaimplementuj kod aplikacji klienta, która będzie używać obiektów serwera
wcześniej zdefiniowanych, zaimplementowanych i utworzonych.
9Skompiluj
ten kod używając normalnego kompilatora wybranego języka
programowania. Nie zapomnij o dołaczeniu podczas kompilacji pliku z
pieńkiem klienta utworzonym z wyrażenia IDL.
Podana wyżej procedura jest typowa, ale może mieć wiele odmian. Niektóre kroki
mogą być pominięte, np. nie ma potrzeby definiowania wyrazenia IDL, jeżeli
zostało ono wcześniej wprowadzone do Interface Repository i został już utworzony
wcześniej pieniek klienta.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 4
listopad 1999
Nasz pierwszy program w CORBA: Counter
Program jest minimalistyczną aplikacją klient-serwer. Jest to dzialająca aplikacja w
Java pod VisiBrokerem. Zakładamy, ze po stronie serwera będzie znajdować się
maciupeńki obiekt zawierający licznik (counter). Dostęp do tego obiektu będzie
określony poprzez atrybut sum (suma przechowywana w liczniku) oraz przez metodę
increment (zwiększ sum o 1). Metoda ta będzie zwracać wartość licznika do klienta.
Co będzie robić nasza aplikacja po stronie klienta?
1) Ustawia licznik na zero;
2) Wywołuje metodę increment 1000 razy;
3) Podaje końcową sumę w liczniku;
4) Drukuje odcinek czasu, w którym działał program.
5) Powinien reagować na wyjątki.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 5
listopad 1999
Counter: wyrażenie IDL
// count.idl
module Counter
{
interface Count
{ attribute long sum;
long increment();
};
};
Wywołanie prekompilatora:
prompt>idl2java count.idl -no_comments -no_tie
program VisiBrokera
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 6
nie generuj dodatkowych klas
dla delegacji
listopad 1999
Counter: klasy i interfejsy Java generowane przez prekompilator
count.idl
CORBA
IDL
{
{
Kompilator
idl2java
Prekompilator
Counter
klasa
klasa
klasa
_st_Count CountHelper CountHolder
Strona klienta Java
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 7
klasa
interfejs
klasa
_CountImplBase
Count
_example_Count
Strona serwera Java
listopad 1999
Jakie to są pliki?
_st_count:
Pieniek klienta, który ma być skompilowany łącznie z jego
aplikacją. Zawiera funkcje szeregujące argumenty metod.
CountHelper
Jest to klasa Java zapewniająca użyteczne funkcje pomocy
dla klientów. (Nie jest na razie dla nas interesująca.)
CountHolder
Jest to klasa Java umożliwiająca traktowanie obiektów typu
Count jako parametrów metod. (Nie jest na razie dla nas
interesująca.)
_CountImplBase
Klasa Java zawierająca szkielet implementacji metod od
strony serwera. Zajmuje się roszeregowaniem argumentów
metod.
Count
Interfejs Java automatycznie generowany z wyrażenia IDL.
Musimy przewidzieć kod, który zaimplementuje ten
interfejs.
_example_Count
Przykładowa klasa, ustalająca ramowe założenia metod,
które musimy wypełnić kodem implementacji.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 8
listopad 1999
Counter: Pieniek klienta generowany automatycznie
_st_count:
Jest to wewnętrzna implementacja
pieńka klienta dla interfejsu Count.
Zajmuje się głównie szeregowaniem
argumentów wołań do serwera.
Nie musimy interesować się tym
kodem. Wszystko, co należy z nim
zrobić, to skompilować i zlinkować go
łącznie z aplikacją klienta.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 9
package Counter;
public class _st_Count extends org.omg.CORBA.portable.ObjectImpl implements Counter.Count {
public java.lang.String[] _ids() {
return __ids;
}
private static java.lang.String[] __ids = {
"IDL:Counter/Count:1.0"
};
public int increment() {
try {
org.omg.CORBA.portable.OutputStream _output = this._request("increment", true);
org.omg.CORBA.portable.InputStream _input = this._invoke(_output, null);
int _result;
_result = _input.read_long();
return _result;
}
catch(org.omg.CORBA.TRANSIENT _exception) {
return increment();
}
}
public void sum(int sum) {
try {
org.omg.CORBA.portable.OutputStream _output = this._request("_set_sum", true);
_output.write_long(sum);
org.omg.CORBA.portable.InputStream _input = this._invoke(_output, null);
}
catch(org.omg.CORBA.TRANSIENT _exception) {
sum(
sum
);
}
}
public int sum() {
try {
org.omg.CORBA.portable.OutputStream _output = this._request("_get_sum", true);
org.omg.CORBA.portable.InputStream _input = this._invoke(_output, null);
int _result;
_result = _input.read_long();
return _result;
}
catch(org.omg.CORBA.TRANSIENT _exception) {
return sum();
}
}
}
listopad 1999
Counter: Szkielet serwera generowany automatycznie
_CountImplBase
Jest to wewnętrzna implementacja
szkieletu serwera dla interfejsu Count.
Zajmuje się głównie rozszeregowaniem
argumentów wołań do serwera.
Nie musimy interesować się tym
kodem. Wszystko, co należy z nim
zrobić, to skompilować i zlinkować go
łącznie z programem serwera.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 10
package Counter;
abstract public class _CountImplBase extends org.omg.CORBA.portable.Skeleton implements Counter.Count {
protected _CountImplBase(java.lang.String name) {
super(name);
}
protected _CountImplBase() {
}
public java.lang.String[] _ids() {
return __ids;
}
private static java.lang.String[] __ids = {
"IDL:Counter/Count:1.0"
};
public org.omg.CORBA.portable.MethodPointer[] _methods() {
org.omg.CORBA.portable.MethodPointer[] methods = {
new org.omg.CORBA.portable.MethodPointer("increment", 0, 0),
new org.omg.CORBA.portable.MethodPointer("_set_sum", 0, 1),
new org.omg.CORBA.portable.MethodPointer("_get_sum", 0, 2),
};
return methods;
}
public boolean _execute(org.omg.CORBA.portable.MethodPointer method,
org.omg.CORBA.portable.InputStream input, org.omg.CORBA.portable.OutputStream output) {
switch(method.interface_id) {
case 0: {
return Counter._CountImplBase._execute(this, method.method_id, input, output);
}
}
throw new org.omg.CORBA.MARSHAL();
}
public static boolean _execute(Counter.Count _self, int _method_id, org.omg.CORBA.portable.InputStream _input,
org.omg.CORBA.portable.OutputStream _output) {
switch(_method_id) {
case 0: {
int _result = _self.increment();
_output.write_long(_result);
return false;
}
case 1: {
int sum;
sum = _input.read_long();
_self.sum(sum);
return false;
}
case 2: {
int _result = _self.sum();
_output.write_long(_result);
return false;
}
}
throw new org.omg.CORBA.MARSHAL();
}
}
listopad 1999
Counter: interfejs w Java generowany z IDL
Count
package Counter;
public interface Count extends org.omg.CORBA.Object {
public void sum(int sum);
public int sum();
public int increment();
}
Musimy napisać kod, który zaimplementuje ten interfejs.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 11
listopad 1999
Counter: przykład klasy implementującej interfejs w IDL
_example_Count
Określany jako
“example servant”
- usługodawca
package Counter;
public class _example_Count
extends Counter._CountImplBase {
public _example_Count(java.lang.String name) {
super(name);
}
public _example_Count() {
super();
}
public int increment() {
// implement operation...
return 0;
}
public void sum(int sum) {
// implement attribute writer...
}
public int sum() {
// implement attribute reader...
return 0;
}
}
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 12
listopad 1999
Counter: Główny program serwera
// CountServer.java: The Count Server main program
Musimy napisać ten program
wg pewnego wzorca.
Inicjalizuje ORB, inicjalizuje
BOA, tworzy obiekt count
po stronie serwera i
rejestruje ten obiekt w
Repozytorium Interfejsów.
class CountServer
{ static public void main(String[] args)
{ try
{ // Initialize the ORB
org.omg.CORBA.ORB orb =
org.omg.CORBA.ORB.init(args, null);
// Initialize the BOA
org.omg.CORBA.BOA boa = orb.BOA_init();
// Create the Count object
CountImpl count = new CountImpl("My Count");
// Export to the ORB the newly created object
boa.obj_is_ready(count);
// Ready to service requests
boa.impl_is_ready();
}
catch(org.omg.CORBA.SystemException e)
{ System.err.println(e);
}
}
}
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 13
listopad 1999
Counter: Szkielet wypełniony implementacją
Klasa _CountImplBase jest rozszerzona poprzez klasę CountImpl, stworzoną z
przykładu _example_Count.
// CountImpl.java: The Count Implementation
class CountImpl extends Counter._CountImplBase
{
// get sum
private int sum;
public int sum()
{ return sum;
// Constructors
}
CountImpl(String name)
{ super(name);
// set sum
System.out.println
public void sum(int val)
("Count Object Created");
{ sum = val;
sum = 0;
}
}
// increment method
public int increment()
{ sum++;
return sum;
}
Razem klasy _CountImplBase i CountImpl
tworzą implementację obiektu po stronie
serwera.
}
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 14
listopad 1999
Counter: program klienta (nasza aplikacja) ost
21.X
// CountClient.java Static Client, VisiBroker for Java
class CountClient
{ public static void main(String args[])
{ try
{ // Initialize the ORB
System.out.println("Initializing the ORB");
org.omg.CORBA.ORB orb =
org.omg.CORBA.ORB.init(args, null);
// Increment 1000 times
System.out.println("Incrementing");
for (int i = 0 ; i < 1000 ; i++ )
{ counter.increment();
}
// Bind to the Count Object
System.out.println("Binding to Count Object");
Counter.Count counter =
Counter.CountHelper.bind(orb, "My Count");
// Calculate stop time; print out statistics
long stopTime = System.currentTimeMillis();
System.out.println("Avg Ping = "
+ ((stopTime - startTime)/1000f)
+ " msecs");
System.out.println("Sum = " + counter.sum());
} catch(org.omg.CORBA.SystemException e)
{ System.err.println("System Exception");
System.err.println(e);
}
// Set sum to initial value of 0
System.out.println("Setting sum to 0");
counter.sum((int)0);
// Calculate Start time
long startTime = System.currentTimeMillis();
}
}
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 15
listopad 1999
Wołanie dynamiczne: krok po kroku (1)
obiekt o jego
1 Spytaj
Otrzymasz InterfaceDef
definicję interfejsu, wołajac metodę get_interface.
obiekt, który opisuje twój obiekt w Repozytorium
Interfejsów.
2Poszukaj metody, która cię interesuje, poprzez wywołanie metody lookup_name
na otrzymanym obiekcie InterfaceDef. Otrzymasz obiekt typu OperationDef.
opis interesującej cie metody, poprzez wywołanie metody describe na
3Odzyskaj
obiekcie OperationDef.
4Utwórz
pustą listę NVList, poprzez metodę create_list. Lista ta będzie
przeznaczona na wartości argumentów twojej metody.
5Zapełń NVlist wartościami argumentów, używając metod add_item i add_value.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 16
listopad 1999
Wołanie dynamiczne: krok po kroku (2)
obiekt Request twojego zlecenia, poprzez wywołanie metody
create_request. Trzeba zakumonikować dla tej metody: 1) nazwę interesującej cie
metody, 2) NVlist, 3) NamedValue w którym będzie zwrócony rezultat metody.
6Utwórz
Wywołaj odległą operację, poprzez wywołanie invoke na obiekcie Request. Jest
7 to wywołanie synchroniczne. Rezultat wywołanie pojawi się w obiekcie Request.
Wykorzystaj resultat i następnie zwolnij obiekt Request, który dalej jest zbędny.
8
Zwolnij NVlist, poprzez wywołanie zlecenia free, które zwalnia miejsce związane
9z NVlist.
Jak widać, zlecenia dynamiczne są dość kłopotliwe. Niektóre czynności są
wspomagane przez ORB.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 17
listopad 1999
Protokoły pomiędzy ORB-ami
Inter-ORB Protocols
Podstawowy cel: współdziałanie pomiędzy ORB-ami wyprodukowanymi przez
różne firmy. Wersje poprzedzające 2.0 nie zapewniały tej własności ze względu na
brak standardu formatu danych i protokółów dla komunikacji pomiędzy ORB-ami.
Bezpośrednie współdziałanie (direct interoperability):
jest możliwe gdy ORB-y są umieszczone w tej samej dziedzinie: rozumieją te same
referencje do obiektów, ten sam system typów w OMG IDL i te same środki bezpieczeństwa.
Współdziałanie bazujące na mostach (bridge-based interoperability):
jest potrzebne do komunikacji ORB-ów z różnych dziedzin. Mają one za zadanie
odwzorować informację specyficzną dla jednego ORB-u w informację właściwa dla innego.
General Inter-ORB Protocol (GIOP) - specyfikuje składnie transferowanej informacji,
format komunikatów. Jest prosty i łatwy w implementacji.
Internet Inter-ORB Protocol (IIOP) - specyfikuje GIOP poprzez transport TCP/IP.
Environment-Specific Inter-ORB Protocols (ESIOP), np. bazujący na OSF DCE.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 18
listopad 1999
Rodzaje usług obiektowych (1)
Object Services
Usługa w zakresie cyklu życiowego (Life Cycle Service). Definiuje operacje
tworzenia, kopiowania, przemieszczania, i usuwania komponentów (obiektów)
będących pod kontrolą danej aplikacji zintegrowanej poprzez standard CORBA.
Usługa w zakresie trwałości (Persistence Service). Definiuje interfejs do
składowania komponentów (obiektów) na trwałych nośnikach, włączając w to
obiektowe bazy danych, relacyjne bazy danych i zwykłe pliki.
Usługa w zakresie nazywania (Naming Service). Pozwala nadać komponentom
(obiektom) nazwy (o hierarchicznej budowie) oraz odzyskać identyfikatory
komponentów (obiektów) na podstawie ich nazw. Usługa pozwala przywiązać
komponenty (obiekty) do istniejącego nazewnictwa katalogów systemów
operacyjnych lub kontekstów nazwowych wg różnorodnych systemów: ISO
X.500, OSF DCE, Sun NIS+, Novell NDS, Internet LDAP.
Usługa w zakresie zdarzeń (Event Service). Pozwala określić, czy dane
komponenty mają reagować (nie reagować) na określone zdarzenia.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 19
listopad 1999
Rodzaje usług obiektowych (2)
Object Services
Usługa w zakresie współbieżności (Concurrency Control Service). Pozwala
zakładać/zdejmować zamki na obiekty (lub inne byty) celem przeciwdziałania
kolizjom transakcji lub wątków.
Usługa w zakresie transakcji (Transaction Service). Przewiduje koordynację
transakcji opartą na dwufazowym potwierdzeniu (2PC) dla prostych i
zagnieżdżonych transakcji.
Usługa w zakresie związków (Relationship Service). Przewiduje dynamiczne
tworzenie/usuwanie powiązań (związków, asocjacji) pomiędzy obiektami,
wymuszanie więzów referencyjnych, oraz nawigację od obiektów do obiektów
wg zdefiniowanych dla nich związków.
Usługa w zakresie udostępniania obiektów na zewnątrz (Externalization
Service). Przewiduje wstawianie i odczytywanie danych do/z komponentów
(obiektów).
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 20
listopad 1999
Rodzaje usług obiektowych (3)
Object Services
Usługa w zakresie zapytań (Query Service). Przewiduje dostęp do obiektów
poprzez różnorodne języki zapytań, wśród nich SQL-92, nowo powstający
standard SQL3, oraz obiektowy język zapytań (standardu ODMG) OQL.
Usługa w zakresie licencji (Licensing Service). Usługa pozwala na pomiary
użycia komponentów (obiektów) oraz wyliczenie opłat za użycie w ramach sesji,
węzła sieci, itd.
Usługa w zakresie dodatkowych własności obiektów (Properties Service).
Pozwala dynamicznie związać z obiektami dowolne nazwane własności
(atrybuty), np. datę utworzenia, datę ostatniej modyfikacji, nazwisko
modyfikującego, itd.
Usługa w zakresie czasu (Time Services). Przewiduje interfejsy do
synchronizowania czasu w środowisku rozproszonym. Pozwala również
definiować zdarzenia wyzwalane przez upływ czasu.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 21
listopad 1999
Rodzaje usług obiektowych (4)
Object Services
Usługa w zakresie ochrony (Security Service). Zapewnia możliwości pełnej
ochrony rozproszonych obiektów. Wspomaga autoryzację, sterowanie dostępem,
tajność i przeciwdziałanie unikaniu zapłaty (non-repudiation). Zarządza także
oddelegowywaniem uwierzytelnień (credentials).
Usługa handlowa (Trader Service). Przewiduje odzyskiwanie informacji o
obiektach na podstawie ich własności, publikować informacje o serwisach
dostarczanych przez obiekty, itd.
Usługa w zakresie kolekcji (Collection Service). Przewiduje interfejsy do
tworzenia najczęściej spotykanych kolekcji (zbiorów, wielozbiorów, sekwencji,
itd.) i manipulacji tymi kolekcjami.
Zestaw usług obiektowych jest rozszerzany w planowanym standardzie CORBA
3.0.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 22
listopad 1999
Zasady projektowania usług obiektowych
• Oddzielenie interfejsu i implementacji
• Referencje do obiektów podlegają kontroli typu poprzez interfejsy
• Klienci zależą od interfejsów, a nie od implementacji
• Stosowane jest wielo-dziedziczenie interfejsów
• Stosowana jest metoda tworzenia podtypów dla rozszerzenia,
ewolucji i specjalizacji funkcjonalności
• Prostota, elastyczność, generyczność serwisów
• Umożliwienie lokalnych i odległych implementacji obiektów
Interfejsy wołań zwrotnych (Callback Interfaces)
- serwer woła wykonanie usług ze strony klienta
- np. przekazywanie danych asynchronicznie do klienta
Brak globalnych przestrzeni identyfikatorów zakres identyfikatorów jest zawsze ograniczony do pewnego kontekstu.
K.Subieta. Bazy danych i inżynieria oprogramowania, Wykład 4, Folia 23
listopad 1999
Download