Download Error - Tecnologías Distribuidas Aplicadas a la Medicina

Document related concepts
no text concepts found
Transcript
TEMA 4: PROGRAMACIÓN DISTRIBUIDA
%!
'(
! "
%
#! $
&
' ') * (+,
(
- ./0
( .40(
%
1'
%16
2%
%
1/../
-
3 % /.0
2%
..02 %
%
8 9:08
1
!
; 1 %<51 =/1+
?(
-
3 % 450
2%
%
1/../
7
!
"
>1499:
>
No existe memoria común
Comunicaciones
No existe un estado global del sistema
Grado de Transparencia
Escalables
Reconfigurables
?(
>
Modelos de Programación Distribuida
Modelo de Paso de Mensajes
Operaciones send y receive
Analizado en asignatura de S.O.
Modelo RPC
Stubs de cliente y servidor
Visión en Java es RMI
Modelos de Objetos Distribuidos
DCOM de Microsoft
Jini de Sun
CORBA de OMG
?(
>
Modelo de Paso de Mensajes
Mecanismo para comunicar y sincronizar entidades
concurrentes que no pueden o no quieren compartir
memoria
Llamadas send y receive
Tipología de las llamadas:
Bloqueadas-No bloqueadas
Almacenadas-No almacenadas (en buffer)
Fiables-No Fiables
En Unix:
Pipes con y sin nombre
En Java:
Sockets.
CTJ (Communicating Threads for Java)
?(
>
Modelo General
SOLICITUD
CLIENTE
SERVIDOR
RESPUESTA
NUCLEO
NUCLEO
RED
?(
>
%
%
#
>
"
%
%
B
@ A $
%
&
%;
%
CB
P
U
E
R
T
O
CLIENTE
SERVIDOR
TCP/UDP
?(
>
App B
App A
Port xxx
Port yyy
App C
Port zzz
PROTOCOLO TCP/UDP
0010111001100010101 Port yyy
Port kkk
P
U
E
R
T
O
CLIENTE
SERVIDOR
Solicitud de conexión
CLIENTE
?(
P
U
E
R
T
O
P
U
E
R
T
O
SERVIDOR
PUERTO
>
D
A
;
%
7
%
%
1
%
%;
% %
7
%
%%
%
Accept()
Socket()
Socket creado y activo
?(
>
%
ServerSocket
"
%
%
&
"
% %
Socket
%
ServerSocket L = newServerSocket (num_puerto)
'%B
%
L.accept();
)%
%
%B
%
?(
C%
>
Socket
%
%%
%
%
"
%
Socket (dirección_IP, puerto);
?(
>
%
4
/
<
E
5
G
?(
7
2
& ServerSocket
& Socket
InputStream
%
%%
OutputStream
%%
F
%
>
&
%# B
$
import java.io.*;
import java.net.*;
public class SocketServidor
{
public static final int port = 8080;
public static void main (String [] args)
throws IOException
{
ServerSocket GenSocket = new ServerSocket(port);
System.out.println("El servidor esta escuchando
en: "+ GenSocket);
try{//espera solicitud conexion desde cliente...
Socket enchufe = GenSocket.accept();
} finally { System.out.println("se cierra la
conexión...");
GenSocket.close();
}
}//main
}//SocketServidor
4
/
<
E
5
?(
7
2
& Socket
InputStream
%%
OutputStream
%%
F
%
%
>
!
import java.io.*;
import java.net.*;
public class SocketCliente
{
public static void main (String [] args)
throws IOException
{
//llamando ordenador despacho de al lado...
InetAddress dir_IP =
InetAddress.getByName("150.214.72.96");
Socket enchufe = new Socket (dir_IP, 8080);
System.out.println("Datos socket creado:
"+enchufe);
}//main
}//SocketCliente
"
A
%
!@
;
%
% %
socket
D 1
& socket
socket
getInputStream()
getOutputStream()
% %
&%
!
(3
&
SocketChannel
?(
7
%&
F
% %
>
>
#$
"
'
()***+
%&
%
%
8
8
%
%
">
7
#
%
"%
3
read-only
%
% %
%
%
&
! >
3 F
%
B
7
"% #
%
%
8!$
¡SE ELIMINA LA MEMORIA COMÚN!
?(
>
2%
A
@
wait(), notify(), notifyAll()
>
% "%
3
7
%
%
%
?(
7
%rendezvous
>
Emisor Listo
;
(synchronized).
D%
3
%
%
% 3
%
Canal
;
&
Receptor Listo
>
,
send (B, mensaje)
Proceso A
rendezvous
Proceso B
receive (A, mensaje)
tiempo
?(
>
&
%
7;
!@
run()
&
&
%
%
%
Canal de Salida
public void run()
{ //codigo ejec.
}
Canal de Entrada
#-
",Process
interfaz csp.lang.Process (análoga a java.lang.Runnable)
public interface csp.lang.Process{
public void run();
}
Procesos de usuario implementan la interfaz:
public class mi_proceso implements Process{
//dato locales al proceso
public mi_proceso(channels y parametros){
//codigo del constructor
}
public void run() //sobreescritura de run
{//código del proceso}
}
?(
>
",
7;
#
@
read >write
%
&
%
%
@
%
;
#
;$
H7 $ 3
%
#
H7
3
?(
>
import csp.lang.*;
import csp.lang.Process.*;
import csp.lang.Integer.*
class Producer implements Process{
ChannelOutput_of_Integer channel;
Integer object;
public Producer (ChannelOutput_of_Integer out){
channel = out;
object = new Integer();
}
public void run(){
object.value=100;
channel.write(object);
}
}? (
>
import csp.lang.*;
import csp.lang.Process.*;
import csp.lang.Integer.*
class Consumer implements Process{
ChannelInput_of_Integer channel;
Integer object;
public Consumer (ChannelInput_of_Integer out){
channel = in;
object = new Integer();
}
public void run(){
channel.read(object);
System.out.println(object);
}
}? (
>
import csp.lang.*;
import csp.lang.Process;
import csp.lang.Integer;
public class P_C_Main{
public static void main (String [] args){
Channel channel = new Channel();
Process modo = new Parallel(new Process[]
new Producer(channel),
new Consumer(channel));
modo.run();
}//main
}// P_C_Main
?(
>
#
#
' % (Channel_of_Boolean)+read/write
'> (Channel_of_Byte)+read/write
" (Channel_of_Char)+read/write
% (Channel_of_Double)+read/write
+%
(Channel_of_Float)+read/write
(Channel_of_Integer)+read/write
)
(Channel_of_Long)+read/write
" (Channel_of_Short)+read/write
7
(Channel_of_Reference)+read/write
& (Channel_of_Object)+read/write
( >(Channel_of_Any)+read/write
?(
>
#
Sequential (Process[] procesos)
Parallel (Process[] procesos)
PriParallel (Process[] procesos)
Con guardas:
Alternative
PriAlternative
?(
>
.
/
01
csp.io.linkdrivers.TCPIP (ó UDP)
%
public TCPIP(remotehost, remoteport, TCPIP.tipo)
#
REALTIME
ASYNCHRONOUS
%
?(
% %
% %
>
import
import
import
Import
csp.lang.*;
csp.lang.Process;
csp.lang.Integer;
csp.io.lindrivers.TCPIP;
public class Prod{
public static void main (String [] args){
final Channel_of_Integer canal =
new Channel_of_Integer new(
TCPIP(“sargo.uca.es”, 1701, TCPIP.REALTIME));
Process par = new Parallel(new Process[]
{new Producer(canal)});
par.run();
}//main
}//Prod
import
import
import
Import
csp.lang.*;
csp.lang.Process;
csp.lang.Integer;
csp.io.lindrivers.TCPIP;
public class Cons{
public static void main (String [] args){
final Channel_of_Integer canal =
new Channel_of_Integer new TCPIP(
(“delfin.uca.es”, 1701, TCPIP.REALTIME));
Process par = new Parallel(new Process[]
{new Consumer(canal)});
par.run();
}//main
}//Cons
!I
+ !( J
http://www.ce.utwente.nl/javapp/
2
3
3
Mayor nivel de abstracción
Llamadas a procedimiento local o remoto indistintamente
Necesita de stubs/skeletons (¡OCULTAMIENTO!)
Registro del servicio
En Unix:
Biblioteca rpc.h
Representación estándar XDR
Automatización parcial: especificación-compilador rpcgen
En Java:
Objetos remotos. Serialización
Paquete java.rmi
Automatización parcial: interfaz-compilador rmic
?(
>
%
%
%
func()
'
8
4 7
/
< KL
2
func(void)
{//codigo
………….
}
%%
%
C
%
%
% %
%MN
2
%
%
7 H
C
'%B
%
7
%
$
%%
%
%
%
&
%
A
?(
>
B
%
%
%
callrpc
+
llamada
normal
rpcreturn
%%
%
RED
H%
%
return
H%
.
/
1
7
7
%
C
7
7O
rpcgen # P
?(
7
%
3
7
D$F
rmic #
7;
$
>
4
5
Especificación Formal
Interface
Cliente
Ejecutable
C
O
M
P
I
L
A
R
?(
Servidor
Ejecutable
Precompilador
rpcgen o rmic
Resguardo
Stub
Ficheros
compartidos
Resguardo
Skeleton
Cliente
Representación
de datos
Servidor
>
C
O
M
P
I
L
A
R
Generador
de
Resguardos
Especificación Formal
Interface
Interfaz del
servidor+asa
create, read
delete, write
Res. Del Servidor
Res. Del Cliente
Read(f,d)
CONECTOR
SERVIDOR
d
CLIENTE
Petición de asa del servidor
?(
Envío de asa
>
6
3
7
%
7
7;
.x
%
7"
/*rand.x*/
program RAND_PROG{
version RAND_VER{
void inicia_aleatorio(long)=1;
double obtener_aleat(void)=2;
}=1;
}=0x3111111;
*
C
% 7"
>
%;
?(
$rpcgen rand.x
%
CB
%
Q
' %
xdr.h
>
32 3
2 $
Permite disponer de objetos distribuidos utilizando Java
Un objeto distribuido se ejecuta en una JVM diferente o remota
Objetivo: lograr una referencia al objeto remoto que permita utilizarlo
como si el objeto se estuviera ejecutando sobre la JVM local
Es similar a RPC, si bien el nivel de abstracción es más alto
Se puede generalizar a otros lenguajes utilizando JNI
RMI pasa los parámetros y valores de retorno utilizando serialización
de objetos.
Objeto
Cliente
Objeto
Servidor
JVM
JVM
?(
>
3
32
RPC
RMI
Carácter y Estructura de diseño
procedimental
Carácter y Estructura de diseño
orientada a objetos
Es dependiente del lenguaje
Es dependiente del lenguaje
Utiliza la representación externa de
datos XDR
Utiliza la serialización de objetos en
Java
El uso de punteros requiere el
manejo explícito de los mismos
El uso de referencias a objetos
locales y remotos es automático
NO hay movilidad de código
El código es móvil, mediante el uso
de bytecodes.
?(
>
'
Un objeto remoto es aquél que se ejecuta en una JVM diferente,
situada potencialmente en un host distinto.
RMI es la acción de invocar a un método de la interfaz de un objeto
remoto.
//ejemplo de llamada a método local
int dato;
dato = Suma (x,y);
//ejemplo de llamada a método remoto (no completo)
IEjemploRMI1 ORemoto =
(IEjemploRMI1)Naming.lookup(“//sargo:2005/EjemploRMI1”);
ORemoto.Suma(x,y);
7!
32
Cliente
Servidor
Stub
Skeleton
Referencia
Remota
Referencia
Remota
Transporte
Transporte
?(
El servidor debe extender RemoteObject
El servidor debe implementar una interfaz
diseñada previamente
El servidor debe tener como mínimo un
constructor (nulo) que lanzará la excepción
RemoteException
El método main del servidor debe lanzar
un gestor de seguridad
El método main crea los objetos remotos
El compilador de RMI (rmic) genera el stub
y el skeleton.
Los clientes de objetos remotos se comunican
con interfaces remotas (diseñadas antes de…)
Los objetos remotos son pasados por referencia
Los clientes que llaman a métodos remotos
deben manejar excepciones.
>
java.rmi.Naming
public static void bind(String name, Remote obj)
public static String[] list(String name)
public static Remote lookup(String name)
public static void rebind(String name, Remote obj)
public static void unbind(String name)
?(
>
K
%
%N
public interfaz
extends Remote
{signaturas métodos}
implements
resultado
ref.metodo(param)
Implementación
de la interfaz
Cliente
new
referencia a interfaz
6
lookup
?(
SERVIDOR
3"
"
bind ó rebind
>
implements
Definir Interfaz Remota
Implementar Interfaz
Remota
$ rmic .class
Skeleton
Stub
JVM
JVM
Implementar Servidor
Implementar Cliente
87
9:32 ;< 6# 387
Escribir el fichero de la interfaz remota.
Debe ser public y extender a Remote.
Declara todos los métodos que el servidor remoto ofrece, pero
NO los
implementa. Se indica nombre, parámetros y tipo de retorno.
Todos los métodos de la interfaz remota lanzan
obligatoriamente la excepción RemoteException
El propósito de la interface es ocultar la implementación de los
aspectos relativos a los métodos remotos.
De esta forma, cuando el cliente logra una referencia a un
objeto remoto, en realidad obtiene una referencia a una
interfaz.
Los clientes envían sus mensaje a los métodos de la interfaz
?(
>
2 : 8 & 3:
6# 387=
/**Ejemplo del interfaz remoto para implementar un RMI
* @author Antonio Tomeu
*Es un servidor remoto aritmético.
*/
//se importan las clases del paquete rmi
import java.rmi.*;
//toda interface remota debe extender la clase Remote
public interface IEjemploRMI1 extends Remote
{
//todo metodo de la interfaz remota debe lanzrar la
//excepcion RemoteException
int Suma(int x, int y) throws RemoteException;
int Resta(int x, int y) throws RemoteException;
int Producto(int x, int y) throws RemoteException;
float Cociente(int x, int y) throws RemoteException;
}
?(
>
87
9:32 )< 2
2 6#7 >6
La implementación del servidor es un fichero que realiza la
implementación de la interfaz definida previamente.
El servidor debe contener una clase que extienda a
UnicasRemoteObject.
Esa misma clase debe implementar a la interfaz remota
(implements)
Debe tener un constructor que lance RemoteException.
El método main debe lanzar un gestor de seguridad.
El método main debe crear los objetos remotos deseados.
El método main debe registrar al menos unos de los objetos
remotos.
?(
>
2 : 2
2 6#7 >6
6# 387=/
3? :3
/**Ejemplo de implementacion del interfaz remoto para
* @author Antonio Tomeu
*/
//se importan los paquetes necesarios
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import java.net.*;
//el servidor debe siempre extender a UnicastRemoteObject
//el servidor debe simpre implementar la interfaz remota
public class EjemploRMI1
extends UnicastRemoteObject
implements IEjemploRMI1
{
un RMI
//aquí viene la implementación de los métodos que se
//declararon en la interfaz
public int Suma(int x, int y)
throws RemoteException
{return x+y;}
public int Resta(int x, int y)
throws RemoteException
{return x-y;}
public int Producto(int x, int y)
throws RemoteException
{return x*y;}
public float Cociente(int x, int y)
throws RemoteException
{ if(y == 0) return 1;
else return x/y;
}
//a continuacion viene el codigo del servidor. Hemos optado
//por incluirlo de manera conjunta, pero podia haber ido en
//un fichero aparte.
//es necesario que haya un constructor (nulo) como minimo, ya
//que debe lanzar RemoteException
public EjemploRMI1()
throws RemoteException
{//super();}
//el metodo main siguiente realiza el registro del servicio
public static void main(String[] args)
throws Exception
{
//crea e instala un gestor de seguridad que soporte RMI.
//el usado es distribuido con JDK. Otros son posibles.
System.setSecurityManager(
new RMISecurityManager());
//Se crea el objeto remoto. Podriamos crear mas si interesa.
EjemploRMI1 ORemoto = new EjemploRMI1();
//Se registra el objeto en la máquina remota. No hay que dar
//nombre de host, y se asume el puerto 1099.
Naming.bind(“Servidor",ORemoto);
System.out.println("Servidor Remoto Preparado");
}
}
87
9:32 @< 4
Fichero de
implementación
de Interfaz
compilado
(Imp.class)
Compilador de RMI
$ rmic imp
#A / B
#:6
Fichero de
stub
(Imp_Stub.class)
Fichero de
skeleton
(Imp_Skel.class)
$ rmic EjemploRMI1
Es necesario que en la máquina remota donde se aloje el servidor se sitúen también
los ficheros de stub y skeleton.
Con todo ello disponible, se lanza el servidor llamando a JVM del host remoto.
En nuestro caso, el servidor remoto se activó en hercules.uca.es sobre el puerto
1099.
$ java EjemploRMI1 &
?(
>
87
9:32 C<3 4 #3:
!@
Naming.bind(“Servidor",ORemoto);
para registrar el objeto remoto creado requiere que el servidor
de nombres esté activo. El nombre de ese servidor es
rmiregistry
Dicho servidor se activa con start rmiregistry en Win32
Dicho servidor se activa con rmiregistry & en Unix.
Se puede indicar como parámetro adicional el puerto que
escucha.
Si no se indica, por defecto es el puerto 1099.
El parámetro puede ser el nombre de un host como en
Naming.bind(“//sargo.uca.es:2005/Servidor",ORemoto);
?(
>
87
9:32 D<
6#
El objeto cliente procede siempre creando un objeto de
interfaz remota.
Posteriormente efectúa una llamada al método
Naming.lookup cuyo parámetro es el nombre y puerto
del host remoto junto con el nombre del servidor.
Naming.lookup devuelve una referencia que se
convierte a una referencia a la interfaz remota.
A partir de aquí, a través de esa referencia el programador
puede invocar todos los métodos de esa interfaz remota
como si fueran referencias a objetos en la JVM local.
?(
>
2 :
6#
/**Ejemplo de implementacion de un cliente para RMI
* @author Antonio Tomeu
*/
import java.rmi.*;
import java.rmi.registry.*;
public class ClienteEjemploRMI1
{
public static void main(String[] args) throws Exception
{
int a = 10;
int b = -10;
//Se obtiene una referencia a la interfaz del objeto remoto
//SIEMPRE debe convertirse el retorno del metodo Naming.lookup
//a un objeto de interfaz remoto
IEjemploRMI1 RefObRemoto =
(IEjemploRMI1)Naming.lookup("//hercules.uca.es/Servidor");
//Llamamos a los metodos del interfaz remoto.
System.out.println(RefObRemoto.Suma(a,b));
System.out.println(RefObRemoto.Resta(a,b));
System.out.println(RefObRemoto.Producto(a,b));
System.out.println(RefObRemoto.Cociente(a,b));
}
}
",Serializable
%;
1
%
H%
&
%
&
%&
Serializable #
%;
?(
%
% &
&
%&
!
%;
@
%
%
7
% $
>
7;
,
import java.io.*;
import java.util.*;
public class cuentabanca
implements Serializable
{ int ccc; float saldo; String Titular;
public cuentabanca(int codigo, float deposito, String
nombre)
{ccc = codigo; saldo = deposito; Titular = nombre;}
public String toString()
{return("codigo = "+ccc+" saldo= "+saldo+" titular=
"+Titular);}
}
",
import java.io.*;
import java.rmi.*;
public interface intefaz
extends Remote
{
boolean deposito(int codigo, float cantidad)
throws RemoteException;
boolean reintegro(int codigo, float cantidad)
RemoteException;
throws
String nomtit(int codigo) throws RemoteException;
int codtit(String nom) throws RemoteException;
/aquí la serializacion es necesaria*/
cuentabanca [] listado() throws RemoteException;
}
4
-policytool
%
System.setSecurityManager(new RMISecurityManager());
&
%
>
)%
%
% @
& SecurityManager
setSecurityManager (clase System)
RMISecurityManager
&
%
% %
Policy
%
Policy.getPolicy()
Policy.setPolicy()
7&
7"
/
?(
"
%
%
3
3
7
% policytool
>
(&
% %
3
%
%> % &
%
7"
.policy
/* AUTOMATICALLY GENERATED ON Fri May 28
19:23:13 CEST 2004*/
/* DO NOT EDIT */
grant {
permission java.net.SocketPermission
"*:1024-65535", "connect,accept, listen,
accept, connect, listen, resolve";
permission java.net.SocketPermission "*:80",
"connect, accept";
permission java.security.AllPermission;
};
(
%
&
&
% %
3
Java –Djava.security=fichero.policy
servidor|cliente
& RMISecurityManager > &
SetSecurityManager
% &
2
:
Microsoft DCOM
Utiliza DCE RPC
Está orientado a un solo sistema operativo
Sin acuerdo
Jini de Sun
Basado en RMI de Java
Muy ligado al lenguaje Java
En sistemas empotrados
CORBA de OMG
Independiente del lenguaje
Marco arquitectónico común
EJB
?(
>
:3 7
:
3!
7 $
ES una tecnología de integración
Resuelve RPC con independencia del lenguaje.
Se puede hacer RPC a métodos remotos de
objetos Java y no-Java
No es necesario conocer la ubicación física del
objeto servidor
Marco de interacción entre objetos distribuidos
estándar e independiente del lenguaje
Especificación de objetos remotos común a
todos los lenguajes a través de IDL
Desarrollado por el OMG (produce
especificaciones, no productos)
?(
>
Elementos de CORBA
OMA (Object Management Architecture): es la
especificación de la interoperabilidad entre
objetos
Core Object Model (Core Object Model):
establece los concepto básicos sobre un objeto,
interfaz, operación.
OMA Reference Architecture: define la
infraestructura de servicios y los mecanismos
subyacentes que permiten la interacción entre
objetos.
ORB (Object Request Broker): es el canal de
comunicación a través del cual los objetos se
solicitan servicios con independencia de la
ubicación física. Existen varias
(JavaIDL)
? implementaciones.
(
>
Todos los elementos de CORBA son objetos
Cada objeto tiene una interfaz e identidad únicos
Cada objeto se puede implementar en un lenguaje
distinto y ejecutarse sobre cualquier HW y SO
CORBA define el bus software que permite la
interoperabilidad entre esta diversidad de
objetos
?(
>
Modelo de Referencia OMA
No
estandarizados
Por OMG
APPLICATION
INTERFACES
Bussines
Healthcare
Finance
Telecom
DOMAIN
INTERFACES
Compound
Object Linking
Help
MOF
COMMON
FACILITIES
OBJECT REQUEST BROKER
Naming
Persistence
Transactions
Concurrency
SERVICIOS A
OBJETOS
Security
Time
Properties
Externalization
Cliente
Implementación del objeto
ORB
?(
>
Estructura del ORB
Invocación Estática
Servidor
Cliente
metodo(param)
rebObjeto.metodo(param)
IDL
Skeleton
IDL
Stub
marshalling
unmarshalling
ORB Core
Interface dependiente del ORB
Stub para cada tipo de objeto
Object
Adapter
Lenguaje de Definición de Interfaces (IDL)
Es un lenguaje de definición de interfaces
orientado a objetos
Especificación común a todos los lenguajes de
una interfaz (métodos y atributos) de objeto
Construye una representación del objeto
distribuido común a cliente y servidor
Soporta herencia
Sintaxis parecida a Java y C++
Precompila (map) a C, C++, Java, Ada, etc.
Ver:
http://java.sun.com/products/jdk/1.2/docs/guide/idl/
?(
>
JavaIDL
Tecnología que integra CORBA en el lenguaje
Java
En java, $idltojava fichero.idl
A partir de J2SE v1.4 es $idlj
Genera el stub del cliente y el skeleton del
servidor (con -fall)+otros ficheros
Ambos automatizan las siguientes tareas (junto
con el ORB):
Ordenamiento y serialización de parámetros (marshalling)
Generan la implementación de la clase de interfaz
Registro y activación de objetos
Localización y conexión (binding) a objetos
?(
>
Herramientas JavaIDL
idlj: compilador de IDL a Java
orbd: proceso demonio que contiene:
Boostrap Service
Servicio de Nombres Transitorios.
Servicio de Nombres Persistentes.
Un Gestor de Servidores
servertool:permite a los programadores de
aplicaciones registrar, dar de baja, arrancar y parar
servidores
tnameserv:Servicio de Nombres Transitorio en
versiones previas de JavaIDL. Se incluye por
compatibilidad hacia atrás.
?(
>
API JavaIDL Básica
org.omg.CORBA
org.omg.CosNaming
org.omg.PortableServer
org.omg.CORBA.ORB
org.omg.PortableInterceptor
org.omg.DynamicAny
?(
>
Compilando IDL
Stubs
Cliente
Interfaz
IDL
Aplicación
Cliente
-fclient
Compilador de IDL
($idltojava)
($idlj) en J2SE
-fserver
-fserver
A partir de J2SE
v1.4
-fall
Skeletons
Servidor
POA
Servidor
Aplicación
Servidor
Implemen.
Servidor
Portable Object Adapter (POA)
El adaptador de objetos conecta una solicitud de cliente al código
que le da servicio (servant) utilizando una referencia a objeto.
Java2SE da soporte POA a través del API correspondiente
POA establece el nexo entre un objeto CORBA y su
implementación (servant)
Establece la correspondencia entre peticiones de entrada y las
diferentes instancias de un mismo objeto.
POA define un espacio de nombres para los servants
Un POA puede tener varios servants
Un servant solo pertenece a un POA
Un servidor puede tener varios POAs activos
Al menos existe el POA raíz
Las relaciones entre un POA y sus servants vienes descritas por las
políticas del POA
POA es un tipo de OA particular, definido en la especificación
CORBA, para lograr:
Implementaciones de objetos portables entre diferentes ORB
Soporte a objetos de identidad persistente
Soporte a la activación transparente de objetos
Servant que soporte identidades simultáneas.
?(
>
Servants
POA
POA Manager
ORB
El Servicio de Nombres
El servicio nombre guarda pares
<nombre, referencia a objeto>
Los nombres están organizados
jerárquicamente (tree-type) en un S.N.
Servidor, crea un servant y lo registra en SN
asociando (bind) una referencia a objeto con un
nombre
Cliente pide al SN que a partir de un nombre le
dé (resolve) una referencia a objeto CORBA
En JavaIDL el SN se activa ejecutando
tnameserv. Por defecto, escucha al puerto 900
No es persistente y está derogado
A partir de J2SE 1.4 orbd proporciona
persistencia si se desea
resolve(A)
Cliente
Servidor
x
Jeraquía de
Nombres
bind(x, ref)
x
ref
NamingContext ncRef =
NamingContext ncRef =
NamingContextHelper.narrow(refObj); NamingContextHelper.narrow(refObj);
NameComponent nc = new
NameComponent nc = new
NameComponent("Impresor Remoto",
NameComponent("Impresor Remoto", "");
"");
NameComponent [] ruta ={nc};
NameComponent [] ruta = { nc };
HolaMundoDistribuido ObjImpresor =
ncRef.rebind(ruta, IRem);
HolaMundoDistribuidoHelper.narrow(ncR
ef.resolve(ruta));
Interacción Cliente/Servidor-Servicio de Nombres
'
Hola Mundo Distribuido Con CORBA1
Especificación IDL de la Interfaz Remota
/**Ejemplo de fichero de especificacion IDL
* @author Antonio Tomeu
*Es una especificacion de un objeto servidor remoto que recibe
como parametro
*una cadena de caracteres y la imprime en la salida estandar del
servidor
*
*/
interface HolaMundoDistribuido {
void Imprimir (in string mensaje);
};
1Utilizando el servicio de nombres no persistente tnameserv ya derogado. Se explica por
compatiblidad hacia atrás.
Hola Mundo Distribuido Con CORBA
Servidor
/**Ejemplo de fichero que implanta un servidor via CORBA
* @author Antonio Tomeu
*/
//CosNaming contiene aspectos relacionados con el servicio de nombre de JavaIDL
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
//Implementación del objeto servidor remoto. Es el codigo del futuro servant
//Debe extender siempre al skeleton generado con el compilador idlj
class ImpresorRemoto
extends _HolaMundoDistribuidoImplBase
{
public void Imprimir(String mensaje)
{System.out.println(mensaje);}
}
//Ahora se implementa la aplicación remota, que realiza las siguientes tareas:
//(1) Crea e inicializa el ORB
//(2) Crea un objeto servidor remoto (servant)
//(3) Lo registra en el ORB
//(4) Lo registra en el servidor de nombre
//(5) Queda a la espera de solicitudes del cliente
public class ServidorRemoto
{
public static void main(String[] args)
throws Exception
{
//se crea e inicializa el ORB El identificador orb es una referencia al
//ORB creado. Utilizamos el ORB propocionado con la distribución JavaIDL
//aunque otros son posibles.
ORB orb = ORB.init(args, null);
//crea un objeto servidor. Por ahora es un objeto java
ImpresorRemoto IRem = new ImpresorRemoto ();
//Se produce el registro de este objeto java en el servicio de nombres
//una vez concluida, es un objeto CORBA (servant)
orb.connect(IRem);
org.omg.CORBA.Object refObj=
orb.resolve_initial_references ("NameService");
//La referencia a tal servicio debe convertirse a una referencia a
//objetos NamingContext.
NamingContext ncRef = NamingContextHelper.narrow(refObj);
//Ahora damos un nombre que sera el utilizado por los clientes para
//enviar solicitudes al objeto servidor
NameComponent nc = new NameComponent("Impresor Remoto", "");
NameComponent [] ruta = { nc };
//Se vincula la referencia pasada a String con la referencia a objeto
ncRef.rebind(ruta, IRem);
//Se esperan peticiones de clientes.
java.lang.Object sinc = new java.lang.Object();
synchronized (sinc)
{sinc.wait();}
}
}
Hola Mundo Distribuido Con CORBA
Cliente
/**Ejemplo de fichero que implanta un servidor via CORBA
* @author Antonio Tomeu
*/
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
public class ClienteHolaMundoDistribuido
{
public static void main(String[] args)
throws Exception
{
//Se crea el ORB del cliente. Se utiliza el proporcionado con JavaIDL.
//Otros son posibles.
ORB orb = ORB.init(args, null);
org.omg.CORBA.Object refObj =
orb.resolve_initial_references ("NameService");
NamingContext ncRef = NamingContextHelper.narrow(refObj);
//Se le pide al Servicio de Nombres que resuelva la referencia para el
//servidor.
NameComponent nc = new NameComponent("Impresor Remoto", "");
NameComponent [] ruta = { nc };
HolaMundoDistribuido ObjImpresor =
HolaMundoDistribuidoHelper.narrow(ncRef.resolve(ruta));
ObjImpresor.Imprimir("Hola Mundoooooooooooooo");
}
}
Hola Mundo Distribuido Con CORBA
Ejecutando el Servicio de Nombres
?(
>
Hola Mundo Distribuido Con CORBA2
Especificación IDL
2Utilizando
el servicio de nombres persistente orbd. Es el estándar de Java IDL a partir
de J2SE y versiones del jdk 1.4 o superiores.