3.3 Aspectos básicos del ORB y el POA

Anuncio
3.3 Aspectos básicos del ORB y el POA
Pseudo-IDL
n
Problema: especificación del interfaz del ORB en el
documento de especificación CORBA
n
n
n
n
¿ En qué lenguaje está especificado ?
En Pseudo-IDL (PIDL)
Similar a IDL
Diferencias
n
n
Los interfaces especificados son locales (el API del ORB)
El mapping de PIDL al lenguaje de implementación puede
desviarse del mapping de IDL (y normalmente se desvía)
Interfaz básica del ORB en PIDL (1)
module CORBA { // PIDL
typedef string ORBid;
typedef sequence<string> arg_list;
interface ORB; // forward declaration
ORB ORB_init(inout arg_list argv, in ORBid orb_identifier);
// ...
interface ORB {
typedef string Objectid;
exception InvalidName {};
void run();
void shutdown(in boolean wait_for_completion);
void destroy();
Object resolve_initial_references(in Objectid identifier)
raises(InvalidName);
string object_to_string(in Object obj);
Object string_to_object(in string str);
// ...
}
};
Interfaz básica del ORB en PIDL (2)
n
CORBA::ORB_init
n
n
n
CORBA::ORB::run
n
n
n
Se queda en un bucle atendiendo peticiones a objetos
remotos
Se debe llamar desde el thread main
CORBA:ORB::destroy
n
n
Método factoría
Devuelve una instancia de un ORB en función de los
parámetros pasados (iremos viendo algunos valores poco a
poco)
Destruye el ORB (liberando recursos)
CORBA::ORB::resolve_initial_references
n
n
Permite obtener referencias iniciales a determinados objetos
Identificadores: RootPOA (POA raíz), NameService (contexto
raíz del servicio de nombres), etc.
Interfaz básica del ORB en PIDL (y 3)
n
CORBA::ORB::object_to_string
n
n
n
CORBA::ORB::string_to_object
n
n
Permite obtener una referencia a un objeto CORBA como
una cadena de caracteres
Es legal aplicar esta operación sobre una referencia nil
Permite obtener una referencia a un objeto CORBA a partir
de su correspondiente representación como cadena de
caracteres
Un mismo ORB puede devolver distintas cadenas de
caracteres en sucesivas invocaciones de
object_to_string sobre una misma referencia
n
n
Por tanto, el valor devuelto no puede utilizarse para realizar
ningún tipo de comparaciones
¡ Las referencias son opacas !
Interfaz básica del ORB en Java
package org.omg.CORBA;
public abstract class ORB {
public static ORB init(String[] args,
java.util.Properties properties) { ... }
public static ORB init() { ... }
public void run() { ... }
public void shutdown(boolean wait_for_completion) { ... }
public void destroy() { ... }
public abstract org.omg.CORBA.Object
resolve_initial_references(String object_name)
throws org.omg.CORBA.ORBPackage.InvalidName { ... }
public abstract String object_to_string(
org.omg.CORBA.Object obj);
public abstract org.omg.CORBA.Object string_to_object(
String str);
public abstract Any create_any();
// ..
}
Inicialización del ORB (1)
n
n
n
init(String[], Properties) es un método estático
factoría para crear una instancia de la clase concreta que deriva
de la clase abstracta org.omg.CORBA.ORB, en función de
parámetros y propiedades
Existe una variante de este método para applets (se estudia
más adelante)
J2SE version 1.2 y superiores incorporan un ORB de CORBA
(poco completo)
n
n
El mecanismo anterior permite “enchufar” cualquier ORB de CORBA
en J2SE
La versión 1.2 no define algunos métodos en
org.omg.CORBA.ORB (ej.: destroy)
Aplicación CORBA
org::omg::CORBA::ORB
com::acme::CORBA::ORB
Inicialización del ORB (2)
n
Los parámetros y propiedades se localizan en el
siguiente orden
n
n
n
n
Parámetro argumentos (puede pasarse null)
Parámetro propiedades (puede pasarse null)
Propiedades del sistema
Fichero orb.properties
n
n
ubicado en <java-home>/lib, donde <java-home> es el
valor de la propiedad del sistema java.home
La variante init() devuelve una instancia singleton
n
Sólo se usa en casos muy concretos (ej.: factoría de
Typecodes)
Inicialización del ORB (y 3)
n
Propiedades estandarizadas
Nombre
n
Significado
omg.ORB.CORBA.ORBClass
Nombre de la clase concreta que
utiliza init(String[],
Properties)
omg.ORB.CORBA.ORBSingletonClass
Nombre de la clase concreta que
utiliza init()
Ejemplo de invocación
java –Dorg.omg.CORBA.ORBClass=com.acme.CORBA.ORB \
-Dorg.omg.CORBA.ORBSingletonClass=\
com.acme.CORBA.ORBSingleton \
es.udc.fbellas.corba.clock.server.Server
n
Ejemplo de inicialización
org.omg.CORBA.ORB orb = ORB.init(args, null);
Terminación limpia de servidores
n
Tanto cliente como servidor deberían llamar a
CORBA::ORB::destroy antes de terminar
n
n
Permite liberar recursos
CORBA::ORB::shutdown permite terminar el bucle
CORBA::ORB::run
n
n
n
n
wait_for_completion==false => retorna inmediatamente e
inicia el proceso de terminación
wait_for_completion==true => espera a que todas las
peticiones actuales terminen
Permite que el servidor ejecute código de finalizacion y llame a
CORBA::ORB::destroy
¿ Cómo llamarlo ?
n
n
n
Desde una opción del entorno de usuario
Una operación especial de un interfaz remoto (con parámetro a false)
=> gestión de aplicaciones
CORBA::ORB::destroy no retorna hasta que todas las
peticiones pendientes terminen
ConsoleServerORBLoopTerminator (1)
package es.udc.fbellas.corba.util.server;
import
import
import
import
java.io.IOException;
java.io.InputStreamReader;
java.io.BufferedReader;
org.omg.CORBA.ORB;
public class ConsoleServerORBLoopTerminator extends Thread {
private final static String END_STRING = "stop";
private ORB orb;
public ConsoleServerORBLoopTerminator(ORB orb) {
this.orb = orb;
/*
* Mark this thread as daemon. It needs to be daemon because
* when the main thread finishes (maybe finished by the
* Implementation Repository Console), the Java Virtual Machine
* should finish.
*/
setDaemon(true);
}
ConsoleServerORBLoopTerminator (y 2)
public void run() {
System.out.println("Type '" + END_STRING +
"' and then <intro> to stop server");
try {
/* Read until END_STRING be typed. */
String typedString;
do {
BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(System.in));
typedString = bufferedReader.readLine();
} while (!typedString.equals(END_STRING));
/* Shutdown ORB. */
orb.shutdown(false);
} catch (IOException e) {
e.printStackTrace();
}
} // run
} // class
En el main del servidor ...
try {
...
/* Install ORB loop terminator. */
System.out.println("Server running");
ConsoleServerORBLoopTerminator terminator =
new ConsoleServerORBLoopTerminator(orb);
terminator.start();
/* Allow the ORB to start processing requests. */
orb.run();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (orb != null) {
orb.destroy();
}
} catch (org.omg.CORBA.SystemException e) {
e.printStackTrace();
}
}
El pseudo interfaz Object en PIDL (1)
module CORBA {
interface Object {
boolean is_nil();
boolean is_a(in string repository_id);
boolean is_equivalent(in Object other_object);
// ..
};
// ...
};
El pseudo interfaz Object en PIDL (2)
n
CORBA::Object::is_nil
n
n
CORBA::Object::is_a
n
n
Permite comprobar si la referencia es nil
Permite comprobar si la referencia es de un tipo
determinado (a partir del correspondiente identificador de
repositorio)
CORBA::Object::is_equivalent
n
n
n
Permite comparar dos referencias a objetos remotos
true => son iguales, y por tanto, apuntan al mismo objeto
remoto
false => no son iguales, y por tanto, no sabemos si se
refieren al mismo objeto remoto
El pseudo interfaz Object en PIDL (y 3)
n
CORBA::Object::is_equivalent (cont)
n
Se ha implementado así por razones de eficiencia
n
n
n
n
n
La comparación se hace localmente sobre las IORs
Existen campos con formato propietario en la IOR (no
necesitan estandarización para interoperabilidad)
Si se intentan comparar dos referencias (a un mismo objeto
remoto) creadas por otro ORB, el resultado seguramente será
false
Incluso la comparación de referencias en un ORB creadas por
él no tiene porque ser fiable
Conclusión: no permite comparar igualdad de objetos
Igualdad de objetos
n
Problema: ¿ cómo comprobar si dos referencias a
objetos apuntan al mismo objeto remoto ?
n
n
n
CORBA::Object::is_equivalent no sirve
Aplicar CORBA::ORB::object_to_string sobre ambas y
comparar tampoco sirve
Una solución
interface Comparable {
typdef long ObjectIdentifier;
ObjectIdentifier getIdentifier();
};
n
n
Este interfaz lo heredan todos los interfaces para los que se
necesite comparar igualdad de objetos
Cada invocación a getIdentifier es una invocación
remota
El pseudo interfaz Object en Java (1)
package org.omg.CORBA;
public interface Object {
boolean _is_a(String identifier);
boolean _is_equivalent(Object that);
// ..
}
El pseudo interfaz Object en Java (2)
n
CORBA::Object::is_nil no se traduce en
ninguna operación
n
Dado que las referencias nil se mapean a Java como
null, basta
if (objectReference == null) {
// ...
}
n
CORBA::Object::is_a
Thermometer thermometer =
controller.findByLocation(“Room01”);
if (thermometer._is_a(“IDL:TCS/Thermostat:1.0”)) {
Thermostat thermostat =
ThermostatHelper.narrow(thermometer);
// Aplicar operaciones específicas a los termostatos
// ..
}
El pseudo interfaz Object en Java (y 3)
n
Otra alternativa más frecuente a _is_a
Thermometer thermometer =
controller.findByLocation(“Room01”);
try {
Thermostast thermostat =
ThermostatHelper.narrow(thermometer);
// Aplicar operaciones específicas a los termostatos
// ...
} catch (org.omg.CORBA.BAD_PARAM e) {
// Era un termómetro.
}
n
_is_a está pensado para aplicaciones que usan el
DII y no disponen de las clases Helper necesarias en
tiempo de compilación
POAs y POAManager (1)
Aplicación servidora
servants
POA
Petición
ORB
POAManager
POA
POAManager
Otros
POAManagers
...
POAManager
...
POA
Otros POAs
POAs y POAManager (2)
n
API
// PIDL
module PortableServer {
interface POA { ... }
interface POAManager { ... }
};
// Java
package org.omg.CORBA.PortableServer;
public interface POA { ... }
public interface POAManager { ... }
n
Una aplicación servidora puede contener múltiples
instancias del POA, de manera que pueda soportar
objetos con distintas características o formas de
implementación de servants
n
Cada instancia tiene asociada un conjunto de políticas (ej.:
multithreading)
POAs y POAManager (3)
n
Todas las aplicaciones disponen al menos del “Root
POA”
org.omg.CORBA.Object rootPOAObject =
orb.resolve_initial_references("RootPOA");
POA rootPOA = POAHelper.narrow(rootPOAObject);
n
Cada POA tiene asociado un POAManager (que
puede encargarse de varios POAs)
n
n
Actúa como una “válvula” que permite regular el flujo de
peticiones que le llegan a los objetos de los POAs que
gestiona
Puede estar en distintos estados
n
n
n
En espera, activo, descartando o inactivo
Dispone de operaciones para transitar entre estados
Para que pueda entregar peticiones a sus POAs tiene que
estar en estado “activo”
POAs y POAManager (y 4)
n
Ejemplo de activación del POAManager
POAManager rootPOAManager = rootPOA.the_POAManager();
rootPOAManager.activate();
n
La operación _this(ORB) de un servant
n
n
n
n
n
Crea un objeto CORBA (si no estaba creado)
Lo registra en el Root POA (si no estaba registrado)
Crea una referencia para el objeto (si no estaba creada)
Retorna la referencia
Ejemplo de _this(ORB)
ClockImpl clockImpl = new ClockImpl();
Clock clock = clockImpl._this(orb);
Implementación de interfaces
n
n
Los interfaces remotos se implementan haciendo uso
de clases skeleton generadas por el compilador de
IDL
Una clase skeleton es una implementación del patrón
Adapter
n
n
Al igual que en el patrón estándar Adapter, existen
dos posibles enfoques
n
n
n
Adapta la interfaz de la clase servant a la invocación de
mensajes recibidos por el ORB
Basado en herencia
Basado en delegación
Transparente al cliente
Enfoque basado en herencia (1)
<<interface>>
Generada por el
org::omg::CORBA::portable::InvokeHandler
compilador de IDL
+ _invoke(method : String, is : InputStream, handler : ResponseHandler) : OutputStream
<<interface>>
es::udc::fbellas::corba::clock::idl:ClockOperations
org::omg::PortableServer::Servant
+ getTimeOfDay() : TimeOfDay
es::udc::fbellas::corba::clock::idl::ClockPOA
Generada por el
compilador de IDL
+ invoke(request : org::omg::CORBA::ServerRequest)
+ _this(orb : org::omg::CORBA::ORB) : es::udc::fbellas::corbajava::clock::idl::Clock
es::udc::fbellas::corba::clock::
Proporcionada por
server::ClockImpl
el programador
+ getTimeOfDay() : TimeOfDay
Enfoque basado en herencia (y 2)
Resto aplicación
cliente
getTimeOfDay
<<interface>>
Clock
POA
invoke
<<interface>>
InvokeHandler
POAManager
ClockPOA
getTimeOfDay
Clase Proxy
Cliente
ORB
ClockImpl
Servidor
Enfoque basado en delegación (1)
Generada por el
<<interface>>
compilador de IDL
org::omg::CORBA::portable::InvokeHandler
+ invoke(method : String, is : InputStream, handler : ResponseHandler) : OutputStream
<<Interface>>
es::udc::fbellas::corba::clock::i
dl:ClockOperations
org::omg::PortableServer::Servant
+ getTimeOfDay() : TimeOfDay
es::udc::fbellas::corba::clock::idl::ClockPOA
Generada por el
compilador de IDL
+ invoke(request : org::omg::CORBA::ServerRequest)
+ _this(orb : org::omg::CORBA::ORB) : es::udc::fbellas::corbajava::clock::idl::Clock
es::udc::fbellas::corba::clock::idl::ClockPOATie
- _delegate : ClockOperations
<<Interface>>
- _poa : POA
Generada por el
<<use>>
compilador de IDL
es::udc::fbellas::corba::clock::idl:ClockOperations
+ ClockPOATie(delegate : ClockOperations)
+ ClockPOATie(delegate : ClockOperations, poa : POA)
+ getTimeOfDay() : TimeOfDay
+ getTimeOfDay() : TimeOfDay
public TimeOfDay getTimeOfDay() {
return _delegate.getTimeOfDay();
es::udc::fbellas::corba::clock::
servertie::ClockImpl
}
+ getTimeOfDay() : TimeOfDay
Proporcionada por
el programador
Enfoque basado en delegación (2)
package es.udc.fbellas.corba.clock.servertie;
import java.util.Calendar;
import es.udc.fbellas.corba.clock.idl.TimeOfDay;
import es.udc.fbellas.corba.clock.idl.ClockOperations;
class ClockImpl implements ClockOperations {
public TimeOfDay getTimeOfDay() {
short hour =
(short) Calendar.getInstance().get(Calendar.HOUR);
short minute =
(short) Calendar.getInstance().get(Calendar.MINUTE);
short second =
(short) Calendar.getInstance().get(Calendar.SECOND);
return new TimeOfDay(hour, minute, second);
}
}
Enfoque basado en delegación (3)
n
Creación del servant y registro en el Root POA
ClockImpl clockImpl = new ClockImpl();
ClockPOATie clockPOATie = new ClockPOATie(clockImpl);
Clock clock = clockPOATie._this(orb);
Enfoque basado en delegación (4)
Resto aplicación
cliente
getTimeOfDay
<<interface>>
Clock
invoke
POA
<<interface>>
InvokeHandler
POAManager
ClockPOA
getTimeOfDay
Clase Proxy
ORB
ClockPOATie
<<interface>>
ClockOperations
getTimeOfDay
ClockImpl
Cliente
Servidor
Enfoque basado en delegación (y 5)
n
El enfoque basado en delegación permite que la clase
que implementa el interfaz remoto extienda (herencia
de implementación) de otra
n
n
Puede facilitar la implementación de herencia (la simple)
En general, ambos enfoques son igual de potentes
Herencia simple
n
IDL
<<interface>>
Thermometer
getTemperature() : Temperature
getLocation() : Location
<<interface>>
Themostat
setTemperature(t : Temperature) : void
Implementación de la herencia simple (1)
n
Enfoque 1 (asumiendo que todo el código está en el mismo
sevidor)
<<interface>>
ThermometerOperations
<<interface>>
ThermostatOperations
ThermometerPOA
ThermometerImpl
ThermostatPOA
1
ThermostatImpl
t: ThermometerImpl
public int getTemperature() {
return t.getTemperature();
}
Implementación de la herencia simple (y 2)
n
Enfoque 2 (asumiendo que todo el código está en el mismo
sevidor)
<<interface>>
ThermometerOperations
ThermometerImpl
ThermostatImpl
1
<<interface>>
ThermostatOperations
ThermometerPOATie
1
ThermostatPOATie
Herencia múltiple
n
IDL
<<interface>>
LandVehicle
<<interface>>
WaterVehicle
<<interface>>
AmphibiousVehicle
Implementación de la herencia múltiple (1)
n
Enfoque 1 (asumiendo que todo el código está en el mismo
sevidor)
<<interface>>
LandVehicleOperations
<<interface>>
WaterVehicleOperations
<<interface>>
AmphibiousVehicleOperations
LandVehiclePOA
WaterVehiclePOA
AmphibiousVehiclePOA
LandVehicleImpl
1
AmphibiousVehicleImpl
l: LandVehicleImpl
w : WaterVehicleImpl
1
WaterVehicleImpl
Implementación de la herencia múltiple (y 2)
n
Enfoque 2 (asumiendo que todo el código está en el mismo
sevidor)
LandVehiclePOATie
AmphibiousVehiclePOATie
WaterVehiclePOATie
1
1
<<interface>>
LandVehicleOperations
<<interface>>
WaterVehicleOperations
1
<<interface>>
AmphibiousVehicleOperations
LandVehicleImpl
1
AmphibiousVehicleImpl
l: LandVehicleImpl
w : WaterVehicleImpl
1
WaterVehicleImpl
Descargar