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
Permite obtener una referencia a un objeto CORBA como
una cadena de caracteres
Es legal aplicar esta operación sobre una referencia nil
CORBA::ORB::string_to_object
n
Permite obtener una referencia a un objeto CORBA a partir
de su correspondiente representación como cadena de
caracteres
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
J2SE incorpora el API del ORB de CORBA y una implementación
por defecto
n
El mecanismo anterior permite “enchufar” cualquier ORB de CORBA
en J2SE
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
n
n
Ubicado en <user-home>, donde <user-home> es el valor
de la propiedad del sistema user.home
ubicado en <java-home>/lib, donde <java-home> es el
valor de la propiedad del sistema java.home
En otro caso, se devuelve la implementación por defecto de
J2SE
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 (con propiedades del sistema)
java –Dorg.omg.CORBA.ORBClass=com.acme.CORBA.ORB \
-Dorg.omg.CORBA.ORBSingletonClass=\
com.acme.CORBA.ORBSingleton \
es.udc.fbellas.corbaws.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.corbaws.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 (y 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
Se explica en el apartado 3.7
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)
Devuelve 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::corbaws::clock::idl:ClockOperations
org::omg::PortableServer::Servant
+ getTimeOfDay() : TimeOfDay
es::udc::fbellas::corbaws::clock::idl::ClockPOA
Generada por el
compilador de IDL
+ invoke(request : org::omg::CORBA::ServerRequest)
+ _this(orb : org::omg::CORBA::ORB) : es::udc::fbellas::corbaxml::clock::idl::Clock
es::udc::fbellas::corbaws::cloc
Proporcionada por
k::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
Herencia simple
n
IDL
<<interface>>
Thermometer
getTemperature() : Temperature
getLocation() : Location
<<interface>>
Thermostat
setTemperature(t : Temperature) : void
Implementación de la herencia simple
n
Asumiendo que todo el código está en el mismo servidor ...
<<interface>>
ThermometerOperations
<<interface>>
ThermostatOperations
ThermometerPOA
ThermometerImpl
ThermostatPOA
1
ThermostatImpl
t: ThermometerImpl
public int getTemperature() {
return t.getTemperature();
}
Herencia múltiple
n
IDL
<<interface>>
LandVehicle
<<interface>>
WaterVehicle
<<interface>>
AmphibiousVehicle
Implementación de la herencia múltiple
n
Asumiendo que todo el código está en el mismo servidor ...
<<interface>>
LandVehicleOperations
<<interface>>
WaterVehicleOperations
<<interface>>
AmphibiousVehicleOperations
LandVehiclePOA
WaterVehiclePOA
AmphibiousVehiclePOA
LandVehicleImpl
1
AmphibiousVehicleImpl
l: LandVehicleImpl
w : WaterVehicleImpl
1
WaterVehicleImpl
Descargar