Download Broker

Document related concepts
no text concepts found
Transcript
Broker in practica: Middleware
Tool Generare Proxy-uri
Biblioteca(API)+ Executabile
Application Developer
Implementari de referinta ale
arhitecturii Broker
Middleware care implementeaza tiparul Broker:
– CORBA: Common Object Request Broker
Architecture. Arhitectura de referinta elaborata de
OMG (Object Management Group)
• Diverse implementari, comerciale sau open
– RMI: Java Remote Method Invocation - Sun
– .NET Remoting – Microsoft
– Web Service Broker
Arhitectura comuna
Server
implements
Client
uses
Remote
Interface
Remote
Object
implements
ServerSide Proxy
ClientSide Proxy
Broker
Exemplu
• Aplicatie distribuita simpla: realizarea unui sistem
StockMarket, care poate fi interogat de la distanta
asupra valorii curente a actiunilor unor companii
specificate
• Middleware (Broker) utilizat - 3 variante:
– CORBA
– RMI
– .NET Remoting
• Se compara:
– Suportul oferit de cele 3 implementari de Broker pentru
dezvoltarea unei aplicatii distribuite simple
– Pasii necesari pentru realizarea aplicatiei
• Exemplul ajuta la intelegerea functionarii unui Broker in
general
Pasi de dezvoltare ai aplicatiei
1. Definire interfata obiect la distanta
INTERFACE
StockMarket
5. Implementare Client
float get_price(Company)
2. Implementare obiect
4. Implementare Server
StockMarketServer
StockMarketClient
StockMarketImpl
3. Generare Proxy
StockMarket
ClientSide PROXY
6. Rulare aplicatie
Broker
3. Generare Proxy
StockMarket
ServerSide PROXY
RMI: Arhitectura
Server
implements
Client
uses
Remote
Interface
Remote
Object
implements
Stub
(ClientSide Proxy)
Remote Reference
Layer
Transport
Layer
Skeleton
(ServerSide Proxy)
RMI - Pas1. Definire interfata
• Se defineste interfata
StockMarket
• Aceasta exporta operatia
get_price:
– Parametru: numele companiei
cotate la bursa
– Rezultat: valoarea actiunilor
Specific RMI:
•Interfata trebuie sa
extinda java.rmi.Remote
•Metodele trebuie sa poata
genera exceptii
RemoteException
package SimpleStocks;
import java.rmi.*;
public interface StockMarket
extends java.rmi.Remote {
float get_price (String Company)
throws
RemoteException;
}
Fisier StockMarket.java
RMI - Pas 2. Implementare Obiect
• Se implementeaza clasa
StockMarketImpl
• Aceasta realizeaza operatia
get_price
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class StockMarketImpl
extends UnicastRemoteObject
implements StockMarket {
public StockMarketImpl() throws
RemoteException {}
Specific RMI:
•Implementarea trebuie
sa extinda
UnicastRemoteObject
public float get_price(String company) {
float price=12345;
return price;
}
}
Fisier StockMarketImpl.java
RMI - Pas 3. Generare Proxy-uri
RMI Stub/Skeleton
Se genereaza automat din implementarea obiectului server
>rmic –v1.1 –keep StockMarketImpl
Rezulta clase pentru stub si skeleton, utilizand conventia de nume:
StockMarketImpl_Stub.class
StockMarketImpl_Skel.class (incepand cu versiunea Java 1.2 implicit nu
se mai genereaza skeleton-ul, de aceea e optiunea –v1.1)
Observatie: incepand cu versiunea Java 1.5, nu mai este necesara pregenerarea stub-ului cu rmic, acesta poate fi generat dinamic la runtime prin
mecanismul de dynamic proxy
Se poate alege daca se doreste utilizarea unui stub pregenerat sau crearea
unui stub cu dynamic proxy, chiar daca ar exista stub-ul pregenerat prin
setarea corespunzatoare a valorii system property
java.rmi.server.ignoreStubClasses
RMI - Pas 4. Implementare Server
• Se implementeaza un program
StockMarketServer, care
creaza un obiect de tip
StockMarket, ce poate fi
accesat de la distanta
• Obiectul creat este inregistrat
sub numele “NASDAQ”
import java.rmi.*;
import SimpleStocks.*;
public class StockMarketServer {
public static void main(String[] args) {
try {
StockMarketImpl stockMarketImpl = new
StockMarketImpl();
Naming.rebind("NASDAQ",
stockMarketImpl );
Specific RMI:
• Naming
} catch (Exception e) {}
}
}
Fisier StockMarketServer.java
RMI - Pas 5. Implementare Client
• Se implementeaza un program
StockMarketClient, care
acceseaza un obiect de tip
StockMarket aflat la distanta, si
invoca operatia get_price
pentru un nume de companie
• Prin intermediul Broker se
localizeaza obiectul cu numele
“NASDAQ”
import java.rmi.*;
import SimpleStocks.*;
public class StockMarketClient {
public static void main(String[] args) {
try {
StockMarket market= (StockMarket)
Naming.lookup("rmi://localhost/NASDAQ");
float price=market.get_price("ABC SRL");
System.out.println("Price is "+price);
Specific RMI:
• Naming.lookup
} catch (Exception e) {
System.out.println("Exception !");}
}
}
Fisier StockMarketClient.java
RMI - Pas 6. Rulare aplicatie
> start rmiregistry
RMI Registry =
non-persistent
Naming Service
> start java StockMarketServer
> start java StockMarketClient
Codul aplicatiei exemplu poate fi download-ad de pe pagina cursului,
de la sectiunea de exemple de cod pentru cursul c7: RMI_StockMarket
CORBA: Arhitectura
Server
Remote
Interface
IDL
Client
Interface
Repository
Dynamic
IDL Stub
Invocation (ClientSide
Interface
Proxy)
ORB
Interface
Remote
Object
IDL Skeleton
(ServerSide
Proxy)
ORB (Object Request Broker)
Object
Adapter
Implem
Repository
CORBA - Pas1. Definire interfata
• Se defineste interfata
StockMarket
• Aceasta exporta operatia
get_price:
– Parametru: numele companiei
cotate la bursa
– Rezultat: valoarea actiunilor
Specific CORBA:
•Interfata se defineste intrun limbaj neutru, CORBA
IDL
module SimpleStocks {
interface StockMarket {
float get_price(in string Company);
};
};
Fisier StockMarket.idl
CORBA - Pas 2. Generare Proxy-uri
CORBA IDL Stub/Skeleton
Se genereaza automat din definitia interfetei IDL
> idl2java StockMarket.idl
Rezulta clasele/fisierele:
Client Stub: _st_StockMarket.java
Server Stub: _StockMarketImplBase.java
CORBA - Pas 3. Implementare Obiect
• Se implementeaza clasa
StockMarketImpl
• Aceasta realizeaza operatia
get_price
Specific CORBA:
•Un obiect accesibil la
distanta trebuie sa extinda
server-side-proxy-ul
generat automat din
descrierea interfetei
import org.omg.CORBA.*;
import SimpleStocks.*;
public class StockMarketImpl extends
_StockMarketImplBase {
public float get_price(in string
company) {
float price=12345;
return price;
}
public StockMarketImpl (String name) {
super(name);
}
}
Fisier StockMarketImpl.java
CORBA - Pas 4. Implementare Server
• Se implementeaza un program
StockMarketServer, care
creaza un obiect de tip
StockMarketImpl, ce poate fi
accesat de la distanta
• Obiectul creat este inregistrat
sub numele “NASDAQ”
Specific CORBA:
•ORB
•BOA
import org.omg.CORBA.*;
Import SimpleStocks.*;
public class StockMarketServer {
public static void main(String[] args) {
try {
ORB orb=ORB.init();
BOA boa=orb.BOA_init();
StockMarketImpl stockMarketImpl=
new StockMarketImpl(“NASDAQ”);
boa.obj_is_ready(stockMarketImpl);
boa. Impl_is_ready();
} catch (Exception e) {}
}
}
Fisier StockMarketServer.java
CORBA - Pas 5. Implementare Client
• Se implementeaza un program
StockMarketClient, care
acceseaza un obiect de tip
StockMarket aflat la distanta, si
invoca operatia get_price
pentru un nume de companie
• Prin intermediul Broker se
localizeaza obiectul cu numele
“NASDAQ”
Specific CORBA:
•ORB
•StockMarketHelper =
proxy generat
import org.omg.CORBA.*;
import SimpleStocks.*;
public class StockMarketClient {
public static void main(String[] args) {
try {
ORB orb=ORB.init();
StockMarket market=
StockMarketHelper.bind(orb,
“NASDAQ”);
market.get_price(“ABC SRL”);
} catch (Exception e) {}
}
}
Fisier StockMarketClient.java
CORBA - Pas 6. Rulare aplicatie
Location service
(numele OSAgent e
specific unei anumite
implementari
CORBA)
> start osagent
> start java StockMarketServer
> start java StockMarketClient
.NET Remoting Architecture
Server
Client
Remote
Interface
Remote
Object
TransparentProxy
RealProxy
Remoting system
Channel
Remoting system
.NET – Pas 1. Definire Interfata Remote
• Se defineste interfata
StockMarket
• Aceasta exporta operatia
get_price:
– Parametru: numele companiei
cotate la bursa
– Rezultat: valoarea actiunilor
Specific .NET:
•Interfata nu contine nimic
special
•Nu este neaparat nevoie
sa fie definita o interfata
public interface StockMarket {
float get_price(string company);
}
Fisier StockMarket.cs
.NET – Pas 2. Definire Obiect Remote
• Se implementeaza clasa
StockMarketImpl
• Aceasta realizeaza operatia
get_price
Specific .NET:
•Obiectul accesibil la
distanta trebuie sa extinda
MarshalByRefObject
using System;
public class StockMarketImpl :
MarshalByRefObject, StockMarket{
public float get_price(string company){
return 12345;
}
}
Fisier StockMarketImpl.cs
.NET – Pas 3. Implementare Server
• Se implementeaza un program
StockMarketServer, care
creaza un obiect de tip
StockMarket, ce poate fi
accesat de la distanta
• Obiectul creat este inregistrat
sub numele “NASDAQ”
Specific .NET:
•ChannelServices
•RemotingServices
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
public class StockMarketServer{
public static void Main(){
StockMarketImpl myStockMarket =
new StockMarketImpl();
TcpChannel m_TcpChan =
new TcpChannel(9999);
ChannelServices.
RegisterChannel(m_TcpChan);
RemotingServices.Marshal(
myStockMarket, "NASDAQ");
System.Console.WriteLine(
"Listening for requests. Press ENTER to quit");
System.Console.ReadLine();
}
}
Fisier StockMarketServer.cs
.NET – Pas 4. Implementare Client
• Se implementeaza un program
StockMarketClient, care
acceseaza un obiect de tip
StockMarket aflat la distanta, si
invoca operatia get_price pentru
un nume de companie
• Prin intermediul Broker se
localizeaza obiectul cu numele
“NASDAQ”
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
public class Client{
public static void Main(){
TcpChannel tcpChan = new TcpChannel();
ChannelServices.RegisterChannel(tcpChan);
StockMarket stockMarket = (StockMarket)
Activator.GetObject(typeof(StockMarket),
"tcp://localhost:9999/NASDAQ");
Specific .NET:
•ChannelServices
•Activator.GetObject
Console.WriteLine(stockMarket.get_price(
"abc SRL"));
}
}
Fisier StockMarketClient.cs
.NET - Pas 5. Rulare aplicatie
> Presupunand ca Windows si .NET Framework este instalat:
> start StockMarketServer
> start StockMarketClient
Codul aplicatiei exemplu poate fi download-ad de pe pagina cursului,
de la sectiunea de exemple de cod pentru cursul c7: .NET Remoting StockMarket
.NET - Pas 6. Creare Proxy ?
• Crearea de Proxy este total transparenta pentru developer-ul de
aplicatii
• Proxy se creaza automat de catre .NET Framework in timpul
executiei cand un client activeaza un obiect la distanta.
Web Services – arhitecture and
standards
IDL model for Web Services
• WSDL acts as an IDL for Web Services distributed
programming model
• Definitions are processed by an IDL compiler to
generate:
– stubs for clients which look like local function calls
– Dispatch routines for the server that invoke the developer’s code
• Tools can generate WSDL descriptions from
implementations
• Tools can generate implementation stubs from WSDL
• Technology examples:
– Java: Axis: wsdl2java, java2wsdl
– .NET: wsdl.exe
Web Service Example
A Web service AddFunction with operation addInt is known through its WSDL:
<wsdl:message name="addIntResponse">
<wsdl:part name="addIntReturn" type="xsd:int" />
</wsdl:message>
<wsdl:message name="addIntRequest">
<wsdl:part name="a" type="xsd:int" />
<wsdl:part name="b" type="xsd:int" />
</wsdl:message>
<wsdl:portType name="AddFunction">
<wsdl:operation name="addInt" parameterOrder="a b">
<wsdl:input message="impl:addIntRequest" name="addIntRequest" />
<wsdl:output message="impl:addIntResponse" name="addIntResponse" />
</wsdl:operation>
</wsdl:portType>
// possible implementation of WS:
// AddFunction.jws
public class AddFunction {
int addInt(int a, int b){
return(a+b);
}
}
How Clients Use Services
• In order to use a service, a Client program needs
only its WSDL (contains abstract interface
description and URI of service endpoint)
• The client program can access the service in
many ways:
– Using Dynamic Invocation Interface ( DII)
– Using generated Stubs from Service WSDL description
– Using Dynamic Proxy
Client – using Generated Stubs
Generate the stubs:
java org.apache.axis.wsdl.WSDL2Java \
http://localhost:8080/axis/AddFunction.jws?wsdl
import localhost.*;
AddFunctionService afs = new AddFunctionServiceLocator();
AddFunction af = afs.getAddFunction();
System.out.println("addInt(5, 3) = " + af.addInt(5, 3));
Client – using generated stubs
• Using generated Stubs from Service WSDL description
– Service to be used is known from the beginning and the WSDL
is available at client development time
– Service Endpoint Interface (SEI): the (Java) programming
language representation of a WSDL port type. Can be
generated automatically by tools from a WSDL
– Stubs (proxies) are classes that implement the SEI. They are
generated from the WSDL description (similar with RMI or
CORBA middleware for distributed object computing)
Alte facilitati oferite de Middleware
• Exemplul anterior ilustreaza doar facilitatile elementare oferite de un
Broker:
– Inregistrarea unui serviciu la Broker
– Localizarea unui serviciu prin Broker
– Obtinerea unei referinte la un obiect la distanta
• In functie de fiecare tehnologie, se mai poate oferi suport si pentru
unele din urmatoarele:
– Invocare dinamica
– Livrare dinamica
– Transferul obiectelor (inclusiv remote objects) ca parametri la serviciile
la distanta – prin valoare sau referinta
– Activarea unui obiect la distanta
– Concurenta in interiorul obiectelor server
– Securitate
– Garbage collection pentru obiectele la distanta
– Interoperabilitatea intre clienti si servere din limbaje diferite
– Bridge cu alte tehnologii de Middleware
Alte facilitati oferite de Middleware - detalii
•
Invocare statica vs. Invocare dinamica
– Invocare statica: daca clientul cunoaste de la design-time care este interfata
serviciului la distanta utilizat:
• Se pot genera clasele de tip ClientSideProxy pentru serviciul respectiv
• Clientul interactioneaza cu acest proxy
• Apelurile sunt hard-codate in codul sursa
– Invocare dinamica: daca clientul nu cunoaste la design-time care este interfata
serviciului la distanta utilizat (acesta va fi descoperit la runtime)
• Apelurile nu pot fi hardcodate in codul sursa al clientului
• Solutie: un mecanism tip Reflection: orice server ofera o operatie de tip invoke, care
primeste ca parametrii operatia concreta si valorile parametrilor
•
Livrare statica vs livrare dinamica
– Livrare statica: Programul server cunoaste de la design-time care sunt obiectele
server pe care le gazduieste
– Livrare dinamica: Obiecte server pot fi create dinamic la runtime
• ServerSideProxy poate fi unul generic, care suporta o operatie de tip invoke ca la
invocarea dinamica
Alte facilitati oferite de Middleware – detalii (cont)
•
Concurenta
– Varianta simpla: Programul server (ServerSideProxy) contine un ciclu in care
accepta cereri si le trateaza secvential
– Server concurent: creaza cate un thread pentru tratarea cererilor
• Problema: Obiectul server poate fi utilizat de thread-uri diferite in acelasi timp – poate
necesita utilizarea unor mecanisme de sincronizare
Alte facilitati oferite de Middleware – detalii (cont)
•
Activarea obiectelor server
–
Varianta simpla: Programul server creaza obiectul server, acesta
exista atat timp cat ruleaza programul server
Activarea obiectelor la cerere: obiectul server este creat doar daca
apare prima cerere pentru el
–
•
Activator: un server care:
–
–
–
•
–
Are evidenta unde se gasesc Implementarile (clasele) din care pot fi instantiate
obiecte server (Exemplu: CORBA: Implementation Repository)
Are evidenta obiectelor server create
Primeste cererea de la client, daca obiectul server nu exista inca - il creaza,
altfel invoca operatia solicitata pe obiectul server
Activator Pattern: Michael Stal, Douglas Schmidt, PLOP 2005
http://www.stal.de/Downloads/Activator.pdf
Exemple: Implementation repository in CORBA, rmid (Java RMI
Activation System Daemon )
Alte facilitati oferite de Middleware – detalii (cont)
•
Garbage collection pentru obiectele server:
– Obiectele server pentru care nu mai exista nici o remote reference pot fi
dezactivate
– Variante:
• Stil cooperativ: clientii anunta cand nu mai au nevoie/elibereaza referinta la server
object, serverul pastreaza evidenta prin contoare
• Brokerul pastreaza evidenta canalelor de comunicatie care sunt active
•
Persistent remote reference
– Un client poate sa detina o remote reference catre un server object, chiar daca
acesta a fost oprit intre timp (accidental sau time-out)
– Daca clientul incearca sa acceseze obiectul server pentru care detine o referinta,
broker-ul trebuie sa il reactiveze si sa il aduca in starea in care acesta a fost
inainte de dezactivare
•
sunt necesare mecanisme de salvare a starii obiectelor server, de aplicat automat
inainte de dezactivare
Alte facilitati oferite de Middleware – detalii (cont)
•
Interoperability intre clienti si servere:
– Interface Description Languages:
• Exista un model comun (model orientat pe obiecte, stabileste un sistem de tipuri,
operatii, interfete, exceptii)
• interfata obiectelor server este descrisa folosind un limbaj de descriere neutru
• Exista reguli (si tool-uri) care mapeaza conceptele IDL pe particularitatile unor limbaje
de programare concrete
Bibliografie suplimentara facultativa
•
Frantisek Plasil, Michael Stal: An Architectural View of Distributed Objects
and Components in CORBA, Java RMI, and COM/DCOM, published in
Software Concepts & Tools, Springer, 1998.
http://dissertations.ub.rug.nl/FILES/faculties/science/2007/m.stal/c3.pdf
•
[POSA2]: Pattern-Oriented Software
Architecture – Volume 2: Patterns for
Concurrent and Networked Objects, Wiley,
2000.
http://www.cs.wustl.edu/~schmidt/POSA/POSA2/
Exercitiu
• Implementarea unui broker foarte simplu, gen
“jucarie” - Toy-ObjectRequestBroker
– Se furnizeaza implementari pentru suportul de
comunicare in retea la nivel de transport de octeti
(ByteSender/Receiver sau Requester/Replyer)
• Descarcati ByteCommunication.zip de pe pagina cursului si
incercati exemplele !
– Exemplul 1: ServerWithSR, ClientWithSR
– Exemplul 2: ServerWithRR, ClientWithRR
– Implementarea nu va folosi alte tehnologii de
Middleware
– Detalii cerinte => Tema 3 laborator
ToyORB: un client
• Este de dorit ca utilizand ToyORB,
StockMarketClient:main sa contina in principiu
urmatoarele:
StockMarket objRef=(StockMarket)
ToyORB.getObjectReference(“NASDAQ”);
float price=objRef.get_price(“ABC SRL”);
Reprezinta operatia
send_request din
Patternul Broker
asa cum e definit in
POSA/Fig.pg.109
•Cauta adresa unui obiect
inregistrat sub numele
NASDAQ
•Creaza si returneaza un
obiect de tip
StockMarketClientSideProxy
StockMarketClientSideProxy.
get_price trimite catre
StockMarketServerSideProxy
parametrul operatiei (numele
companiei cotate la bursa) si
receptioneaza rezultatul (pretul
curent)
ToyORB: un server
• Este de dorit ca utilizand ToyORB,
StockMarketServer:main sa contina in principiu
urmatoarele:
StockMarket obj=new StockMarketImpl
ToyORB.register (obj, StockMarket, “NASDAQ”);
•Inregistreaza obj creat, care
implementeaza serviciul
StockMarket si are numele
NASDAQ
•Creaza un obiect de tip
StockMarketServerProxy care
intra in asteptarea cererilor de la
clienti
ToyORB: Varianta Forwarder-Receiver
2 canale de comunicatie diferite, unul pentru transmis parametri,
unul pentru transmiterea rezultatului
deliver ( marshal ( “ABC SRL” ) unmarshal ) receive
StockMarket
ClientProxy
F
R
R
receive ( unmarshal ( 1234.5 ) marshal ) deliver
Dezavantaj:
tiparul F-R presupune
participanti cu statut egal
=> ar trebui ca si clientii sa
se inregistreze (sau ORB
sa le asigneze un nr de
port in mod transparent)
ToyORB
NamingService
Config.db
“StockMarketClient”: IP, Port
“NASDAQ”: IP, Port
F
StockMarket
ServerProxy
ToyORB: Varianta Requester-Replyer
StockMarket
ClientProxy
Marshaller StockMarket
ServerProxy
Marshaller
deliver_and_wait_feedback
Requester
receive_transform_and_send_feedback
Replyer
ToyORB
NamingService
deliver_and_wait_feedback:
deliver cererea urmata de
receptia rezultatului pe acelasi
canal de comunicatie (socket)
Config.db
“NASDAQ”: IP, Port
receive_transform_and_
send_feedback: receive
cererea urmata de
transmiterea rezultatului
pe acelasi canal de
comunicatie
ToyORB: Implementare Proxy-uri
send_request
StockMarketClientSideProxy:
•
•
•
Are un Requestor r
Are un Marshaller m
Pentru a rezolva operatia get_price:
pack_data – Cu ajutorul lui m – marshal,
transforma parametri de intrare(numele
companiei) intr-un sir de octeti
forward_ – Cu ajutorul lui r deliver_and_wait_feedback,
request
transmite catre ServerSideProxy sirul
de octeti parametru si receptioneaza un
sir de octeti reprezentand rezultatul
– Cu ajutorul lui m - unmarshal,
unpack_data
transforma sirul de octeti obtinut in
valoarea rezultatului (pretul)
Cu text rosu italics sunt
identificate operatiile
prin numele cu care apar in
Pattern-ul Broker
call_service
StockMarketServerSideProxy:
•
•
•
Are un Replyer r
Il cunoaste pe StockMarketImpl s
Are un Transformer t : primeste un sir de octeti si
returneaza sirul de octeti transformat
•
Pentru a realiza operatia get_price de ori de cate
ori este solicitat:
While (true)
r.receive_transform_and_send_feedback(t(s));
– Receptioneaza sirul de octeti reprezentand
parametrii, t(s) il transforma in sir de octeti de
forward_
tip rezultat, care vor fi transmisi inapoi la
response
client
ServerTransformer:
•
•
Are un Marshaller m
Pentru a rezolva transformarea:
– cu ajutorul lui m – unmarshal, reconstruieste
unpack_data parametri de intrare (numele companiei)
– Apeleaza operatia de la StockMarketImpl s si
obtine rezultatul
run_service
– Cu ajutorul lui m - marshal, transforma
rezultatul (pretul) in sir de octeti
pack_data
ToyORB: suport pt servere mai complexe
•
•
Este de dorit ca sa se poata accesa la distanta si obiecte care
implementeaza interfete mai complexe (cu mai multe operatii).
De exemplu:
public interface ComplexStockMarket {
float get_price (String Company);
String whois_highest_today();
String whois_lowest_today();
}
In acest caz, un client va putea accesa serviciile la distanta in felul urmator:
ComplexStockMarket objRef=(ComplexStockMarket)
ToyORB.getObjectReference(“NASDAQ”);
float price=objRef.get_price(“ABC SRL”);
String junk=objRef.whois_lowest_today();
Pentru aceasta, ClientSideProxy trebuie sa includa in sirul de octeti produs la
operatia marshal si informatia referitoare la ce operatie s-a cerut.
ServerSideProxy va deduce in operatia unmarshal despre ce operatie este vorba
ToyORB: Atentie la dependente !
• ToyORB trebuie sa poata fi folosit pentru orice tip de aplicatii
(StockMarket, ComplexStockMarket, InfoServer, MathServer, etc –
si orice alt tip, necunoscut la momentul crearii ToyORB)
• ToyORB nu poate sa depinda deloc de cod specific aplicatiilor !
– Marshaller: trebuie sa poata transforma in bytes orice combinatie de
parametrii
– ToyORB.getObjectReference(String ServerName) trebuie sa poata sa
creeze si returneze un obiect proxy client corespunzator tipului aplicatiei
(StockMarketClientSideProxy, MathServerClientSideProxy,
InfoServerClientSideProxy, etc), dar fara sa depinda de aceasta !
• Posibila solutie: utilizarea Reflection pentru crearea obiectului de
tipul corespunzator
Scenarii de localizare a serverelor
ToyORB.getObjectReference(“NASDAQ”);
StockMarketImpl
NASDAQ
StockMarketClient1
StockMarketClient2
StockMarketImpl
NIKKEI
ToyORB.getObjectReference(StockMarket);
ToyORB.getObjectReference(“TimisInfo”)
InfoClient1
InfoServerImpl
TimisInfo
Scenarii de localizare a serverelor
StockMarketImpl
NASDAQ
StockMarketClient1
StockMarketImpl
NIKKEI
StockMarketClient2
InfoClient1
NamingService Address
127.0.0.1, 1111
NamingService
NASDAQ, StockMarket,127.0.0.1,1112
NIKKEI, StockMarket, 127.0.0.1,1113
TimisInfo, InfoServer, 127.001,1114
InfoServerImpl
TimisInfo
Scenarii de utilizare: Inregistrare Server
StockMarketImpl
NASDAQ
ToyORB.register
Requester
NamingService Address
127.0.0.1, 1111
Replyer
NamingService
NASDAQ, StockMarket, 127.0.0.1, 1112
Scenarii de utilizare: Serverul ready
StockMarketImpl
NASDAQ
StockMarketClient1
StockMarketServerProxy
Replyer
NamingService Address
127.0.0.1, 1111
Replyer
NamingService
NASDAQ, StockMarket, 127.0.0.1, 1112
Scenarii de utilizare: getObjectReference
StockMarketImpl
NASDAQ
StockMarketClient1
StockMarketServerProxy
Replyer
ToyORB.getObjectRef
Requester
NamingService Address
127.0.0.1, 1111
Replyer
NamingService
NASDAQ, StockMarket, 127.0.0.1, 1112
Scenarii de utilizare: s-a obtinut referinta
StockMarketImpl
NASDAQ
StockMarketClient1
StockMarketServerProxy
StockMarketClientProxy
Replyer
Requester
NamingService Address
127.0.0.1, 1111
Replyer
NamingService
NASDAQ, StockMarket, 127.0.0.1, 1112
ToyORB: Implementare NamingService
• NamingService mai complex (Trader):
– Localizarea unui obiect la distanta se face dupa numele sau
(“NASDAQ”)
– Localizarea unui obiect la distanta se face dupa descrierea
serviciului pe care il furnizeaza (StockMarket) -> se obtine o
referinta spre unul din obiectele inregistrate ca furnizand acest
serviciu
• Implementarea NamingService: sub forma de server
care are o adresa fixa cunoscuta de catre ToyORB
– ToyORB:getObjectReference
– ToyORB:register
Interactioneaza fiecare cu
NamingService
dupa tiparul Requester-Replyer
Scopul unui ORB
• Un Object Request Broker este o infrastructura pentru dezvoltarea
de aplicatii distribuite:
• Se refoloseste ca infrastructura in MULTE
aplicatii DIFERITE, NECUNOSCUTE
dezvoltatorului sau!
• Consecinte:
– Esential: ORB NU poate depinde in nici un fel
de cod specific acestor aplicatii
– Pentru cresterea “usability”: este de dorit ca Broker-ul
sa sprijine dezvoltatorul de aplicatii si in problema
scrierii proxy-urilor
• Tool-uri pentru generarea automata a proxy-urilor
ToyORB: Generarea automata a proxy-urilor
• Punct de start: scrieti manual proxy-urile pentru cel putin 2 aplicatii
diferite, pentru a identifica un Template comun
ToyORB: Implementare Proxy-uri StockMarket
send_request
StockMarketClientSideProxy:
•
•
•
Are un Requestor r
Are un Marshaller m
Pentru a rezolva operatia get_price:
pack_data – Cu ajutorul lui m – marshal,
transforma parametri de intrare(numele
companiei) intr-un sir de octeti
forward_ – Cu ajutorul lui r deliver_and_wait_feedback,
request
transmite catre ServerSideProxy sirul
de octeti parametru si receptioneaza un
sir de octeti reprezentand rezultatul
– Cu ajutorul lui m - unmarshal,
unpack_data
transforma sirul de octeti obtinut in
valoarea rezultatului (pretul)
Cu text rosu italics sunt
identificate operatiile
prin numele cu care apar in
Pattern-ul Broker
call_service
StockMarketServerSideProxy:
•
•
•
Are un Replyer r
Il cunoaste pe StockMarketImpl s
Are un Transformer t : primeste un sir de octeti si
returneaza sirul de octeti transformat
•
Pentru a realiza operatia get_price de ori de cate
ori este solicitat:
While (true)
r.receive_transform_and_send_feedback(t(s));
– Receptioneaza sirul de octeti reprezentand
parametrii, t(s) il transforma in sir de octeti de
forward_
tip rezultat, care vor fi transmisi inapoi la
response
client
ServerTransformer:
•
•
Are un Marshaller m
Pentru a rezolva transformarea:
– cu ajutorul lui m – unmarshal, reconstruieste
unpack_data parametri de intrare (numele companiei)
– Apeleaza operatia de la StockMarketImpl s si
obtine rezultatul
run_service
– Cu ajutorul lui m - marshal, transforma
rezultatul (pretul) in sir de octeti
pack_data
ToyORB: Template-uri pentru proxy
•
•
Se presupune un server cu interfata ServiceX
ServiceXClientSideProxy:
–
–
Class ServiceXClientSideProxy implements ServiceX
Fiecare operatie definita in interfata ServiceX este implementata in felul urmator:
•
•
•
•
Creaza mesajul (marshal): numele operatiei, (numarul si tipurile parametrilor), valorile parametrilor
Deliver_and_wait_feedback
Extrage din mesajul de raspuns valoarea rezultatului (conform tipului returnat de operatie) si o
returneaza
Observatie:
–
ServiceXClientSideProxy este o clasa care implementeaza interfata ServiceX !
–
Varianta1 (general aplicabila): tipul ServiceX este cunoscut de dinainte, Codul pentru
ServiceXClientSideProxy este generat automat in faza de design si este instalat pe
calculatorul clientului (Exemple: CORBA, RMI in java 1.1)
Varianta2 (pentru tehnologii care suporta dynamic class loading): codul pentru
ServiceXClientSideProxy este generat automat, dar nu trebuie pre-instalat pe fiecare
calculator client de dinainte, ci poate fi download-at dinamic la runtime (Exemplu RMI)
Varianta 3 (pentru tehnologii care suporta forme de run time code generation - dynamic
proxy): codul clasei ServiceXClientSideProxy este generat automat la runtime (nu trebuie
utilizate tool-uri de generare in faza de design), (Exemple: RMI in java dupa1.5 si .NET
Remoting)
–
–
ToyORB: Template-uri pentru proxy (cont)
• Se presupune un server cu interfata ServiceX
• ServiceXServerSideProxy:
– Class ServiceXServerSideProxy:
• are o referinta la obiectul server ServerXImpl
• Contine “server-loop” (while (true)
receive_transform_sendfeedback)
– Class ServiceXServerTransformer implements
ServerTransformer
• Primeste referinta la obiectul server ServerXImpl
• Extrage din mesajul primit (unmarshal) numele operatiei si valorile
parametrilor
• Invoca operatia pe obiectul server
– Varianta 1: secventa de cod de tip “switch-case” (Java 1.1, CORBA)
– Varianta 2: prin Reflection -> nu mai depinde de tipul ServiceX ->
devine un ServerSideProxy generic (Java 1.2, .NET)
• Creaza mesajul de raspuns(marshal) cu rezultatul invocarii operatiei
ToyORB: Generarea automata a proxy-urilor
• Posibilitati de generare automata a proxy-urilor:
– In mod diferit in RMI, CORBA, .NETRemoting
• RMI-style (in varianta java.rmi.server.ignoreStubClasses = false):
– Tool de generare (echivalent lui rmic)
• Intrare: Implementarea obiectului remote (class). Poate fi analizat
prin reflection.
• Iesire: fisiere sursa proxy-uri (denumite dupa o conventie de
numire), care vor fi compilate si link-uite cu clientul respectiv
serverul
• CORBA-style:
– Tool de generare (echivalent lui idl2java)
• Intrare: Interfata obiectului remote. Poate fi analizata cu parsing de
text.
• Iesire: ca si in cazul anterior, fisiere sursa proxy-uri (denumite dupa
o conventie de numire), care vor fi compilate si link-uite cu clientul
respectiv serverul
ToyORB: Generarea automata a proxy-urilor (cont)
• Posibilitati de generare automata a proxy-urilor:
– In mod diferit in RMI, CORBA, .NETRemoting
• .NET Remoting-style sau RMI
(in varianta
java.rmi.server.ignoreStubClasses =true)
– Existenta Proxy-urilor este complet transparenta pentru dezvoltatorul
de aplicatii
• Broker-ul creaza in mod dinamic clasele pentru proxy-uri si apoi le
instantiaza
– Dynamic proxy
» Java.lang.reflect.Proxy
http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/P
roxy.html
» .NET emit
http://msdn.microsoft.com/en-us/library/5kyyyeh2.aspx
Related documents