Systemy Rozproszone

Transkrypt

Systemy Rozproszone
Systemy Rozproszone - Ćwiczenie 6
1
Obiekty zdalne
Celem ćwiczenia jest stworzenie obiektu zdalnego świadczącego prostą usługę
nazewniczą. Nazwy i odpowiadające im punkty końcowe będą przechowywane przez obiekt w tablicy. Metoda insert dodaje punkt końcowy (hostName,
portNumber) o nazwie s. Metoda search zwraca indeks w tablicy dla nazwy
s. Metody getHostName i getPort zwracają nazwę hosta i port dla zadanego
indeksu w tablicy.
1.1
Interfejs obiektu zdalnego
Pierwszym krokiem przy tworzeniu obiektu zdalnego jest określenie jego interfejsu, który dziedziczy po klasie java.rmi.Remote. Każda metoda interfejsu musi
być zadeklarowana jako zgłaszająca wyjątek java.rmi.RemoteException.
/∗ p l i k RMINameService . j a v a ∗/
import j a v a . rmi . ∗ ;
public i n t e r f a c e RMINameService extends Remote {
public int s e a r c h ( S t r i n g s ) throws RemoteException ;
public int i n s e r t ( S t r i n g s , S t r i n g hostName ,
int portNumber ) throws RemoteException ;
public int g e t P o r t ( int i n d e x ) throws RemoteException ;
public S t r i n g getHostName ( int i n d e x ) throws
RemoteException ;
}
1.2
Implementacja obiektu zdalnego
Klasa dla obiektu zdalnego musi dziedziczyć po java.rmi.server.UnicastRemoteObject
i implementować interfejs, który został zadeklarowany w rozdziale 1.1. W metodzie main tworzony jest obiekt zdalny klasy RMINameServer. Nastepnie, ten
obiekt jest eksportowany przy pomocy metody UnicastRemoteObject.exportObject().
W wyniku eksportu otrzymujemy namiastkę obiektu zdalnego (typu RMINameService),
1
którą należy skojarzyć z określoną nazwą w rejestrze RMI przy poprzez wywołanie Registry.rebind()
import j a v a . rmi . ∗ ;
import j a v a . rmi . r e g i s t r y . ∗ ;
import j a v a . rmi . s e r v e r . UnicastRemoteObject ;
public c l a s s RMINameServer extends UnicastRemoteObject
implements RMINameService {
f i n a l int maxSize = 1 0 0 ;
private S t r i n g [ ] names = new S t r i n g [ maxSize ] ;
private S t r i n g [ ] h o s t s = new S t r i n g [ maxSize ] ;
private int [ ] p o r t s = new int [ maxSize ] ;
private int d i r S i z e = 0 ;
public RMINameServer ( ) throws RemoteException {
}
public int s e a r c h ( S t r i n g s ) throws RemoteException {
f o r ( int i = 0 ; i < d i r S i z e ; i ++) {
i f ( names [ i ] . e q u a l s ( s ) ) {
return i ;
}
}
return −1;
}
public int i n s e r t ( S t r i n g s , S t r i n g hostName , int
portNumber ) throws RemoteException {
int o l d I n d e x = s e a r c h ( s ) ;
i f ( ( o l d I n d e x == −1) && ( d i r S i z e < maxSize ) ) {
names [ d i r S i z e ] = s ;
h o s t s [ d i r S i z e ] = hostName ;
p o r t s [ d i r S i z e ] = portNumber ;
d i r S i z e ++;
return 1 ;
}
return 0 ;
}
public int g e t P o r t ( int i n d e x ) throws RemoteException {
return p o r t s [ i n d e x ] ;
}
2
public S t r i n g getHostName ( int i n d e x ) throws
RemoteException {
return h o s t s [ i n d e x ] ;
}
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
try {
RMINameServer o b j = new RMINameServer ( ) ;
UnicastRemoteObject . u n e x p o r t O b j e c t ( obj , true ) ;
System . out . p r i n t l n ( " E x p o r t i n g . . . " ) ;
RMINameService s t u b = ( RMINameService )
UnicastRemoteObject . e x p o r t O b j e c t ( obj , 0 ) ;
Registry r e g i s t r y ;
i f ( true ) {
// s t w o r z e n i e nowego r e j e s t r u na l o c a l h o s c i e
r e g i s t r y = LocateRegistry . createRegistry (1099) ;
System . out . p r i n t l n ( "New␣ r e g i s t r y ␣ c r e a t e d ␣on␣
localhost ") ;
}
else {
System . out . p r i n t l n ( " L o c a t i n g ␣ r e g i s t r y . . . " ) ;
// p o d l a c z e n i e do i s t n i e j a c e g o r e j e s t r u na
localhoscie
r e g i s t r y = LocateRegistry . getRegistry (" localhost "
);
System . out . p r i n t l n ( " R e g i s t r y ␣ l o c a t e d " ) ;
}
r e g i s t r y . r e b i n d ( "MyNameServer" , s t u b ) ;
System . out . p r i n t l n ( " RMINameService ␣bound , ␣ ready " ) ;
} catch ( E x c e p t i o n e ) {
System . e r r . p r i n t l n ( " RMINameService ␣ e x c e p t i o n : " ) ;
e . printStackTrace () ;
}
}
}
1.3
Klient
import j a v a . rmi . ∗ ;
import j a v a . rmi . r e g i s t r y . ∗ ;
3
public c l a s s RMIClient {
public s t a t i c void main ( S t r i n g [ ] a r g s ) {
try {
System . out . p r i n t l n ( " L i s t ␣ o f ␣ r e g i s t e r e d ␣REMOTE␣
objects : ") ;
f o r ( S t r i n g s : Naming . l i s t ( " // l o c a l h o s t " ) ) {
System . out . p r i n t l n ( s ) ;
}
System . out . p r i n t l n ( " G e t t i n g ␣ r e g i s t r y " ) ;
Registry reg = LocateRegistry . getRegistry ( "
localhost ") ;
System . out . p r i n t l n ( " G e t t i n g ␣ i n t e r f a c e " ) ;
RMINameService s = ( RMINameService ) r e g . lookup ( "
MyNameServer" ) ;
System . out . p r i n t l n ( "Got␣ i n t e r f a c e " ) ;
s . i n s e r t ( " foo " , " 1 9 2 . 1 6 8 . 1 . 1 " , 10000) ;
s . i n s e r t ( " bar " , " 1 9 2 . 1 6 8 . 1 . 2 " , 1 0 0 0 0 ) ;
s . i n s e r t ( " baz " , " 1 9 2 . 1 6 8 . 1 . 3 " , 1 0 0 0 0 ) ;
String search_string = " foo " ;
int i = s . s e a r c h ( s e a r c h _ s t r i n g ) ;
i f ( i != −1) {
System . out . p r i n t l n ( s . getHostName ( i ) + " : " + s .
getPort ( i ) ) ;
}
else {
System . out . p r i n t l n ( s e a r c h _ s t r i n g + " ␣ not ␣ found " ) ;
}
}
catch ( E x c e p t i o n e ) {
e . printStackTrace () ;
}
}
}
2
Zadanie 1 - Kalkulator
Zaimplementuj kalkulator jako obiekt zdalny.
4
3
Zadanie 2 - Bank
Stwórz prosty system bankowy, która umożliwa klientowi banku zalogowanie się
do systemu i przeprowadzenie podstawowych operacji na swoim koncie.
Metody zdalne do zaimplementowania po stronie serwera:
/∗
A u t o r y z a c j a k l i e n t a na p o d s t a w i e pary ( numer konta , kod
pin ) i r o z p o c z e c i e s e s j i ( zalogowanie )
Parametry :
a c c o u n t : numer k o n t a
p i n : p i n p r z y p i s a n y do k o n t a
Uwagi :
Metoda zwraca t o k e n a u t o r y z a c y j n y , k t o r y j e s t
generowany i zapamietywany
p r z e z s e r w e r ( l o s o w y c i a g znakow ) . Token p o t r z e b n y j e s t
do a u t o r y z a c j i
k o l e j n y c h o p e r a c j i wykonywanych na tym k o n c i e
∗/
S t r i n g a u t h o r i z e ( int account , int p i n )
/∗
Zapytanie o stan konta
Parametry :
t o k e n : t o k e n a u t o r y z a c y j n y otrzymany po z a l o g o w a n i u
Zwraca s t a n k o n t a ( i l o s c p i e n i e d z y na k o n c i e )
∗/
double g e t B a l a n c e ( S t r i n g token )
/∗
Wplata p i e n i e d z y na k o n t o
Parametry :
t o k e n : t o k e n a u t o r y z a c y j n y otrzymany po z a l o g o w a n i u
v a l u e : kwota do w p l a t y
∗/
void d e p o s i t ( S t r i n g token , double v a l u e )
/∗
Wyplata p i e n i e d z y z k o n t a
Parametry :
t o k e n : t o k e n a u t o r y z a c y j n y otrzymany po z a l o g o w a n i u
v a l u e : kwota do w y p l a t y
Zwraca f a l s z , gdy b r a k srodkow na k o n c i e do
przeprowadzenia operacji
5
∗/
boolean withdraw ( S t r i n g token , double v a l u e )
/∗
P r z e l e w p i e n i e d z y na i n n e k o n t o
Parametry :
t o k e n : t o k e n a u t o r y z a c y j n y otrzymany po z a l o g o w a n i u
a c c o u n t : nr k o n t a na k t o r e z o s t a n a p r z e l a n e p i e n i a d z e
v a l u e : kwota do w y p l a t y
Zwraca f a l s z , gdy b r a k srodkow na k o n c i e do
przeprowadzenia operacji
∗/
boolean withdraw ( S t r i n g token , int account , double v a l u e )
/∗
Konczy s e s j e ( w y l o g o w a n i e )
Uwagi :
Serwer p o w i n i e n usunac t o k e n ( o i l e j e s t on p r a w i d l o w y )
∗/
void bye ( S t r i n g token )
Przykład użycia kodu po stronie klienta:
B a n k i n g S e r v i c e atm = . . . . . . // o b i e k t z d a l n y
o d p o w i e d z i a l n y za o b s l u g e k o n t bankowych
S t r i n g token = atm . a u t h o r i z e ( 1 2 3 4 5 6 , 1 1 1 1 ) ;
i f ( token != null ) {
// wplacam 100 z l na k o n t o
atm . d e p o s i t ( token , 1 0 0 ) ;
// sprawdzam s t a n k o n t a
double b a l a n c e = atm . g e t B a l a n c e ( token ) ;
System . out . p r i n t l n ( " Stan ␣ konta : ␣ "+b a l a n c e ) ;
// wyplacam p i e n i a d z e z k o n t a
atm . withdraw ( token , 5 0 ) ;
// wplacam p i e n i a d z e na k o n t o nr 112233
atm . t r a n s f e r ( token , 1 1 2 2 3 3 , 2 5 ) ;
// ponownie sprawdzam s t a n k o n t a
System . out . p r i n t l n ( " Stan ␣ konta : ␣ "+atm . g e t B a l a n c e ( token )
);
}
6