La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

PROCESAMIENTO DISTRIBUIDO UTILIZANDO CORBA Universidad del Zulia Facultad de Ingeniería Instituto de Cálculo Aplicado Prof. Carlos Arévalo, M.Sc.

Presentaciones similares


Presentación del tema: "PROCESAMIENTO DISTRIBUIDO UTILIZANDO CORBA Universidad del Zulia Facultad de Ingeniería Instituto de Cálculo Aplicado Prof. Carlos Arévalo, M.Sc."— Transcripción de la presentación:

1 PROCESAMIENTO DISTRIBUIDO UTILIZANDO CORBA Universidad del Zulia Facultad de Ingeniería Instituto de Cálculo Aplicado Prof. Carlos Arévalo, M.Sc.

2 CONTENIDO Introducción 1. ¿Qué es CORBA? 2. Características del CORBA 3. ¿Porqué usar “Objetos distribuidos”? Arquitectura del CORBA ORB (Object Request Broker) 1. Descripción 2. Componentes IDL (Lenguaje de Definición de Interfaces) 1. Stubs 2. Esqueletos

3 Referencias 1. Cómo hacer solicitudes a objetos CORBA 2. Cómo obtener referencias a objetos CORBA Adaptadores de Objetos (Objetct Adapters) 1. Portable Object Adapter (POA) 2. Manejadores de sirvientes Servicios Comunes 1. Servicio de nombres (Naming Service) CONTENIDO

4 INTRODUCCIÓN

5 CORBA: Common Object Request Broker Architecture. Arquitectura del administrador de solicitudes de objetos CORBA es una tecnología para el manejo de objetos distribuídos Especificación de una arquitectura e interfaz que permite a una aplicación hacer solicitudes a objetos Independiente del sistema operativo, de la plataforma hardware y del lenguaje de programación Los clientes y servidores pueden residir en la misma computadora o estar distribuidos INTRODUCCIÓN

6  Invocación transparente de objetos Computador AComputador B Proceso A Proceso B Proceso C TCP/IP Comunicación entre procesos Llamada directa Objeto Cliente INTRODUCCIÓN

7 El ORB es el mediador entre el cliente y el servidor ORB clienteORB servidor Solicitud Objeto CORBA Referencia de objeto Flujo real de la solicitud Conexión lógica Aplicación clienteAplicación servidora INTRODUCCIÓN

8 CORBA fue desarrollado por el OMG (Object Management Group) Una organización formada por más de 700 empresas que desarrollan, venden y utilizan software El OMG desarrolló OMA (Object Management Architecture) como estrategia fundamental para promover el uso de la tecnología orientada a objetos INTRODUCCIÓN

9 OMA: Object Management Architecture - Arquitectura para la manipulación de objetos ORB (Object Request broker) Application objects Objetos aplicación Common facilities Facilidades comunes Common services Servicios comunes INTRODUCCIÓN

10 Componentes de OMA  Objetos de aplicación (application objects). Son los programas de aplicación que intercambian información durante su ejecución  Servicios comunes. Son objetos que ofrecen servicios fundamentales, tales como servicios de directorio, transacciones y persistencia. Estos servicios están estandarizados para que sean interoperables INTRODUCCIÓN

11 Componentes de OMA  Facilidades comunes. Son objetos que ofrecen servicios cuya funcionalidad responde a necesidades particulares de los dominios de aplicación  Object request broker (ORB). El ORB es el encargado de permitir que los demás componentes de OMA puedan interactuar INTRODUCCIÓN

12 El ORB (Object Request Broker - Administrador de Solicitudes a Objetos) es el componente central del OMA CORBA es la especificación del ORB El OMG no produce software. Los ORBs son desarrollados y distribuidos por las empresas miembro En la actualidad existen varios ORBs que se adhieren bien a las especificaciones CORBA Esto hace que las aplicaciones CORBA sean interoperables INTRODUCCIÓN

13 Objetos distribuidos La programación orientada objetos se presta de forma natural para el procesamiento distribuido Un objeto distribuido es un objeto que puede recibir solicitudes a través de la red INTRODUCCIÓN

14 ¿Por qué objetos distribuidos?... construir_mensaje( s ); enviar_mensaje( B, s ); esperar_respuesta( r ); decodificar( r ); procesar_respuesta( );... While (true) { esperar_mensaje( s ); decodificar_mensaje( s ); procesar_solicitud( ); construir_mensaje( r ); enviar_mensaje(A, r); } Aplicación A. Supervisión remota Debe interrogar a B para obtener lecturas de sensores Aplicación B. Al ser interrogada por A lee un sensor y devuelve la lectura Red INTRODUCCIÓN

15 Problemas:  La construcción, envío y decodificación de mensajes no tiene nada que ver con la aplicación propiamente dicha  Las operaciones dependen del protocolo de red utilizado (TCP-IP, IPX-SPX, etc.)  Son operaciones orientadas a entrada - salida INTRODUCCIÓN

16 Utilizando objetos distribuidos:... Sensor s; // objeto remoto temperatura = s.leer();... int Sensor.leer() {... }... orb.run(); Aplicación AAplicación B La operación s.leer() es una solicitud que se hace al objeto remoto El ORB se encarga de codificar el mensaje, enviarlo a la máquina remota, decodificarlo, entregarlo a la aplicación remota y repetir el proceso a la inversa para devolver el resultado INTRODUCCIÓN

17 Las principales tecnologías de objetos distribuidos son:  COM/DCOM (distributed component object model). Tecnología de objetos distribuidos de Microsoft, la cual está siendo sustituida por.NET. .NET. Tecnología de objetos distribuidos de Microsoft, actualmente en desarrollo.  RMI (remote method invocation). Tecnología de objetos distribuidos de Java.  SOAP (simple object access protocol). Tecnología de objetos distribuidos basada en XML y http.  CORBA (common object request broker architecture). Tecnología de objetos distribuidos del OMG. INTRODUCCIÓN

18 ARQUITECTURA

19 Componentes principales de CORBA  Clientes  Objetos CORBA  ORB (Object request broker - Administrador de solicitudes a objetos)

20 Núcleo del ORB Stubs IDL Dynamic Invocation Interface Interfaz ORB Dynamic skeleton interface ClienteObjeto ORB Object Adapter  Estructura del CORBA ARQUITECTURA IDL Skeleton

21 Cliente: Un ente que hace una solicitud a un objeto CORBA Servidor: Un ente capaz de recibir una solicitud de un cliente, realizar una acción (o múltiples acciones) en respuesta a dicha solicitud y devolver un resultado También recibe el nombre de Objeto, o Implementación de objeto (object implementation) Los demás componentes del diagrama constituyen el ORB ARQUITECTURA

22 ORB (OBJECT REQUEST BROKER)

23 ORB Object Request Broker (Administrador de solicitudes a objetos) Función: Enviar solicitudes a objetos y devolver las respuestas a los clientes Característica más importante: transparencia

24 El ORB debe ocultar lo siguiente:  Ubicación de los objetos.  El cliente no sabe donde reside el servidor: en el mismo proceso, en la misma computadora o en diferentes computadoras conectadas en red  Implementación de objetos.  El cliente no sabe cómo se ha implementado el servidor, que lenguaje fue usado, en que sistema operativo o en que plataforma de hardware está implementado  Estado del servidor.  El cliente no sabe si el servidor está activo o no  Mecanismo de comunicación.  El cliente no sabe que mecanismo de comunicación se está usando (TCP/IP, memoria compartida, llamada local, etc.) ORB

25 Componentes del orb  Núcleo del ORB (ORB core)  IDL (lenguaje de definición de interfaces)  Stubs IDL  Interfaz de invocación dinámica (DII)  Esqueletos IDL (IDL skeletons)  Interfaz del ORB  Object adapters ORB

26 Núcleo del ORB  Es el mediador entre los clientes y los servidores ORB clienteORB servidor Solicitud Objeto CORBA Referencia de objeto Flujo real de la solicitud Conexión lógica Aplicación clienteAplicación servidora ORB

27 IDL IDL. Lenguaje de definición de interfaces  Un lenguaje que permite definir las interfaces CORBA  Interfaz CORBA:  Un conjunto de operaciones y sus parámetros  Compilador IDL: toma como entrada un archivo fuente IDL y produce como salida: 1. Stubs IDL 2. Esqueletos IDL (IDL skeletons)

28 IDL. Lenguaje de definición de interfaces  El IDL es independiente del lenguaje de programación  Existen compiladores IDL para diversos lenguajes de programación: C, C++, Java, Pascal, y otros  Soporta diferentes tipos de datos, incluyendo tipos básicos (enteros, floats, etc.), estructuras, objetos, arreglos dinámicos, strings, entre otros. IDL

29 interface Pozo { int devolverProducciónCrudo(); int devolverProducciónGas(); } Compilador IDL class Pozo { int devolverProduccionCrudo(); int devolverProduccionGas(); } Archivo fuente en lenguaje IDL Stub IDL (archivo fuente en lenguaje C++) Esqueleto IDL (archivo fuente en lenguaje C++) class Pozo { int devolverProduccionCrudo(); int devolverProduccionGas(); } IDL

30 Stubs IDL  Son archivos fuente, en un lenguaje dado, que permiten que un cliente haga solicitudes a objetos CORBA que implementan las interfaces definidas  Son generados automáticamente por el compilador IDL a partir de interfaces CORBA  Los stubs deben ser incorporados en los programas cliente  Contienen el código necesario para canalizar la solicitud al ORB IDL

31 Esqueletos IDL (IDL skeletons)  Son archivos fuentes que se incorporan al programa que implementa el o los servidores definidos en el fuente IDL  Son generados automáticamente por el compilador IDL a partir de interfaces CORBA  Contienen los esqueletos (definiciones de las clases sin la implementación de los métodos) de las interfaces CORBA IDL

32 IDL. Lenguaje de definición de interfaces  Ejemplo: module aplpozos { interface Pozo { long devolverId(); long devolverProduccionCrudo(); }; IDL

33 IDL. Implementación del objeto PozoImpl: import org.omg.CORBA.*; import aplpozos.*; public class PozoImpl extends PozoPOA { static int valores[] = {120, 200, 140, 180, 300, 280}; int id; int produccionCrudo; PozoImpl(int id) { this.id =id; produccionCrudo = valores[id]; } public int devolverId() { return id; } public int devolverProduccionCrudo() { return produccionCrudo; } IDL

34 IDL. Implementación del objeto PozoImpl: import org.omg.CORBA.*; import org.omg.PortableServer.*; import aplpozos.*; public class AplicacionPozos { public static void main(String[] args) { try { //iniciar el orb ORB orb = ORB.init( args, null ); // iniciar el POA org.omg.CORBA.Object obj = orb.resolve_initial_references("RootPOA"); POA poa = POAHelper.narrow(obj); poa.the_POAManager().activate();... IDL

35 IDL. Implementación del objeto PozoImpl:... // crear un pozo PozoImpl pi = new PozoImpl(2); obj = poa.servant_to_reference(pi); Pozo p = PozoHelper.narrow(obj); // hacer solicitudes int prod = p.devolverProduccionCrudo(); System.out.println("Produccion: "+prod); } catch( UserException e ) { System.err.println(e); } catch( SystemException e ) { System.err.println(e); } IDL

36 IDL (INTERFACE DEFINITION LANGUAGE)

37 Interfaces module pozos { interface Pozo { string devolverId(); long devolverProduccionCrudo(); long devolverProduccionGas(); void devolverProduccion(out long prodCrudo, out long prodGas); void actualizarProduccionCrudo(in long produccion); void actualizarProduccionGas(in long produccion); }; interface FabricaPozos { Pozo crearPozo(in string id); }; IDL

38 Bindings o mappigns  El IDL es independiente del lenguaje de programación utilizado para implementar las aplicaciones  Los mappings determinan como se ven las interfaces en distintos lenguajes de programación  Un mapping utiliza los recursos de cada lenguaje para poder tener acceso a objetos CORBA IDL

39 Módulos module aplpozos { module pozos { interface Pozo { long id; long devolverProduccionCrudo(); long devolverProduccionGas(); }; IDL

40 Ejercicio no. 1. Cree la interfaz Pozo presentada anteriormente. Siga los siguientes pasos: 1. Utilice un editor de texto para definir la interfaz. 2. Use un compilador IDL para generar el binding correspondiente a Java de la interfaz Pozo. 3. Edite los archivos PozoOperations.java y Pozo.java y estudie su contenido. IDL

41 Tipos de datos básicos  Tipos enteros: 1. Short/unsigned short. Enteros de 16 bits 2. long/unsigned long. Enteros de 32 bits 3. Long long/unsigned long long. Enteros de 64 bits  Tipos de Punto flotante 1. float. IEEE std 754-1985 2. double. IEEE std 754-1985 IDL

42 Tipos de datos básicos  Tipo char  Caracteres de 8 bits basados en el juego de caracteres ISO Latin-1 (8859.1). Pueden sufrir transformaciones al ser transmitidos a través del sistema de comunicación  Tipo wchar  Caracteres de más de un byte, por ejemplo Unicode. El tamaño y el juego de caracteres no está especificado IDL

43 Tipos de datos básicos  Tipo Boolean  TRUE y FALSE.  Tipo Octet  Una cantidad de 8 bits que no sufre ninguna conversión al ser transmitida por el sistema de communicación  Tipo Any  Una variable de tipo any puede contener valores de cualquier otro tipo de dato IDL

44 Tipos de datos complejos  Estructuras 1. Similares a las estructuras en lenguaje C struct ubicacion { long latitud; long longitud; };  Tipos enumerados 1. Similares al tipo enum de Pascal y C 1. emum TipoPozo { flujo_natural, gas_lift, bes }; IDL

45 Tipos de datos complejos  Tipos definidos por el usuario  Similar al typedef de C++  typedef short Identificador;  Arreglos  Arreglos multidimensionales. Sintaxis similar a la del lenguaje C  typedef long a[10];  typedef long b[20][20]; IDL

46 Tipos de datos complejos  Secuencias  Son arreglos unidimensionales con un tamaño máximo fijo y una longitud que puede variar en tiempo de ejecución  typedef sequence s; // delimitada  typedef sequence s; // sin limite  Se pueden declarar secuencias de secuencias  typedef sequence s2;  typedef sequence > s; IDL

47 Tipos de datos complejos  Strings  Son secuencias de caracteres con o sin límite  string s; // sin límite  string s ; // con limite IDL

48 Herencia  Una interfaz puede derivarse de otra  Puede haber herencia múltiple module pozos { interface Pozo { string devolverId(); long devolverProduccionCrudo(); long devolverProduccionGas(); void devolverProduccion(out long prodCrudo, out long prodGas); void actualizarProduccionCrudo(in long produccion); void actualizarProduccionGas(in long produccion); };... IDL

49 Herencia... interface PozoGasLift : Pozo { void actualizarPresion(in long presion); long devolverPresion(); }; interface PozoBES : Pozo { void actualizarCorriente(in double c); double devolverCorriente(); }; IDL

50 Excepciones  CORBA permite el manejo de excepciones remotas  Para que una aplicación pueda lanzar una excepción, ésta debe ser declarada:... exception IdNoValido { long id; string mensaje; };... void asignarId(in long id) raises (IdNovalido);... IDL

51 REFERENCIAS

52 Para hacer una solicitud el cliente utiliza una referencia a un objeto Cuando un nuevo objeto es creado se crea una nueva referencia Los objetos son creados en la aplicación servidora Para poder hacer una solicitud el cliente debe obtener, de alguna manera, la referencia al objeto

53 Inicialmente el cliente no tiene acceso a la referencia de un nuevo objeto creado en la aplicación servidora Pozo Crear pozo ORB Referencia al Pozo ? ORB Aplicación clienteAplicación servidora REFERENCIAS

54 A continuación se presenta un mecanismo simple para obtener una referencia // crear un pozo PozoImpl p = new PozoImpl(2); org.omg.CORBA.Object obj = poa.servant_to_reference(p); Pozo pozo = PozoHelper.narrow(obj); REFERENCIAS

55 Si se tiene una referencia al objeto, se puede hacer una solicitud de la siguiente manera: Pozo p;// declaración de variable // obtener referencia;.... // hacer solicitud int prod = p.devolverProduccionCrudo(); REFERENCIAS

56 Convertir una referencia a string  Una aplicación servidora puede pedir al ORB que convierta la referencia en un string (una cadena de caracteres)  El string se puede almacenar en un archivo o base de datos  La aplicación cliente puede leer la referencia-string del archivo y pedir al ORB que la convierta de nuevo en referencia viva Se requiere que tanto el programa cliente como el servidor tengan acceso a archivos comunes Por esta razón este método no puede ser usado en todos los casos REFERENCIAS

57 Pozo Referencia al pozo Solicitudes ORB Aplicación clienteAplicación servidora ORB... Datos.dat Pozo.ref... Archivos en disco Escribir referencia Leer referencia  Obtener una referencia desde un archivo REFERENCIAS

58 Escribir una referencia a un archivo // Arrancar el ORB org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,nul)... // Crear el objeto PozoImpl p = new PozoImpl(2); org.omg.CORBA.Object obj = poa.servant_to_reference(p); // convertir la refencia en string String ref = orb.object_to_string( obj ); // Escribir la referencia a un archivo FileWriter out = new FileWriter("pozo.ref"); out.write( ref ); out.close(); REFERENCIAS

59 Leer una referencia de un archivo // Leer la referencia del pozo de un archivo FileReader f = new FileReader("pozo.ref"); BufferedReader r = new BufferedReader(f); String ref = r.readLine(); // convertir la refencia-string en refencia CORBA org.omg.CORBA.Object obj = orb.string_to_object(ref); // hacer el narrow a Pozo Pozo p = PozoHelper.narrow(obj); // verificar si la operación fue correcta if( p == null ) { System.out.println("Error al obtener la referencia"); System.exit( 1 ); } // invocar operaciones int prod = p.devolverProduccionCrudo(); REFERENCIAS

60 Ejemplo: aplicaciones cliente y servidor separadas. Servidor: import java.io.*; import org.omg.CORBA.*; import org.omg.PortableServer.*; import aplpozos.*; public class Servidor { public static void main(String[] args) { try { //inicializar el orb ORB orb = ORB.init( args, null ); // inicializar el POA POA poa = POAHelper.narrow( orb.resolve_initial_references("RootPOA")); poa.the_POAManager().activate(); // crear un Pozo PozoImpl pozoImpl = new PozoImpl( 1 ); // crear la referencia org.omg.CORBA.Object obj = poa.servant_to_reference( pozoImpl );... REFERENCIAS

61 Ejemplo: aplicaciones cliente y servidor separadas. Servidor... // convertir la referencia a string FileWriter out = new FileWriter("pozo.ref"); out.write( orb.object_to_string( obj ) ); out.close(); // esperar solicitudes orb.run(); } catch( UserException e ) { System.err.println(e); } catch( SystemException e ) { System.err.println(e); } catch( IOException e ) { System.err.println(e); } REFERENCIAS

62 Ejercicio no. 2. Implemente la aplicación presentada en esta sección. Siga los siguientes pasos: 1.Agregue una nueva operación devolverProduccion void devolverProduccion(out long ProdCrudo, out long ProdGas); 2.Implemente las clases PozoImpl, Servidor y Cliente presentadas en esta sección REFERENCIAS

63 Obtener referencias mediante una fábrica  El cliente solicita a un objeto fábrica (factory object) la creación de un nuevo objeto  El objeto fábrica crea el objeto en la aplicación servidora y devuelve una referencia al mismo  El objeto fábrica es un objeto CORBA y se debe implementar igual que cualquier otro objeto (no hay fábricas predefinidas)  Para obtener una referencia de esta manera es necesario previamente tener la referencia del objeto fábrica REFERENCIAS

64  Obtener referencias mediante una fábrica Objeto fábrica Pozo Crear pozo ORB Referencia Crear pozo Referencia Solicitudes ORB Aplicación clienteAplicación servidora Referencia al objeto fábrica Referencia al pozo REFERENCIAS

65 Obtener una referencia al crear un objeto // Aplicación cliente... Pozo p; p = fabricaPozos.crearPozo( ); int prod = p.devolverProducciónCrudo( );... REFERENCIAS

66 Declaración IDL de una fábrica interface FabricaPozos { Pozo crearPozo(in long id); }; REFERENCIAS

67 Implementación de la fábrica class FabricaPozosImpl extends FabricaPozosPOA { public Pozo crearPozo(String idPozo) { try { PozoImpl pozoImpl = new PozoImpl(idPozo); org.omg.CORBA.Object obj = poa.servant_to_reference(pozoImpl); Pozo p = PozoHelper.narrow(obj); return p; } catch( SystemException se ) { return null; } catch( UserException ue ) { return null; } REFERENCIAS

68 Aplicación servidora... public class Servidor { public static void main(String[] args) { try { //inicializar el orb y el POA... // crear la fábrica FabricaPozosImpl fabrica = new FabricaPozosImpl(); // crear la referencia org.omg.CORBA.Object obj = poa.servant_to_reference(fabrica); // convertir la referencia a string FileWriter out = new FileWriter("fabrica.ref"); out.write( orb.object_to_string( obj ) ); out.close(); // esperar solicitudes orb.run(); } // capturar excepciones... } REFERENCIAS

69 Aplicación cliente public class Cliente { public static void main(String args[]) { try { // inicializar el orb ORB orb = ORB.init( args, null ); String ref = new BufferedReader( new FileReader("fabrica.ref")).readLine(); org.omg.CORBA.Object obj = orb.string_to_object( ref ); // Obtener la referencia a la fabrica FabricaPozos fabrica = FabricaPozosHelper.narrow( obj ); // verificar si se obtuvo la referencia if (fabrica == null) { System.out.println("La referencia no es válida"); System.exit( 1 ); } // crear un pozo y usar un pozo Pozo p = fabrica.crearPozo(1); int prod = p.devolverProduccionCrudo(); }... REFERENCIAS

70 Ejercicio no. 3. Implemente la clase fábrica de pozos. Siga los siguientes pasos: 1.Defina la interfaz FabricaPozos. 2.Implemente el objeto FabricaPozosImpl. 3.Modifique las aplicaciones Cliente y Servidor para que utilicen la fábrica. REFERENCIAS

71 Obtener referencias mediante un servicio de nombres El cliente puede invocar un servicio de búsqueda para obtener una referencia CORBA define un servicio de nombres: Interoperable Name Service Este servicio no crea objetos, sino que almacena referencias a objetos e información asociada (nombre, propiedades) y entrega la referencia cuando se le hace la solicitud El Name Service es un objeto CORBA, de manera que para obtener una referencia mediante este servicio se requiere tener una referencia al mismo REFERENCIAS

72 Name Service ORB Aplicación cliente Referencia al Name service Referencia al pozo Resolver(“Pozo”) Referencia al pozo Pozo Aplicación servidora ORB Solicitudes Registrarse  Obtener una referencia mediante un servicio de nombres REFERENCIAS

73 Utilizar la operación “resolve_initial_reference” Se puede obtener una referencia a objetos que implementan servicios básicos mediante la operación “resolve_initial_reference” Esta solicitud se hace directamente al ORB. No requiere una referencia previa... Object obj = null; obj = orb.resolve_initial_reference(“NameService”);... REFERENCIAS

74 Para que el ORB pueda “resolver referencias iniciales” es necesario configurarlo para indicarle como localizar los servicios básicos Cada paquete CORBA tiene su propia mecanismo de configuración Por ejemplo el ORB “JavaORB” utiliza un archivo de configuración donde se definen las referencias iniciales de la siguiente manera: REFERENCIAS

75 Archivo de configuración del JavaORB # # Java ORB Initial References # version 1.2 # # Object Loader ObjectLoader Host(xxxx), ObjectId(IDL:JavaORB/loader:1.0), Key(ObjectLoader), port(2000) # Naming Service NamingService Host(xxxx), ObjectId(IDL:omg.org/CosNaming/NamingContext:1.0), Key(NamingRoot), Port(2001) # Interface Repository InterfaceRepositoryHost(cli29c5), ObjectId(IDL:org.omg/CORBA/Repository:1.0), Key(IRRoot), Port(2004) REFERENCIAS

76 OBJECT ADAPTERS (ADAPTADORES DE OBJETOS)

77 OBJECT ADAPTERS Los adaptadores de objetos (object adapters) se ubican entre los objetos y el ORB El ORB delega en el Adaptador de objetos las operaciones de crear y destruir referencias y la activación y desactivación de objetos El primer object adapter fue el BOA - basic object adapter Posteriormente se desarrolló el POA - portable object adapter

78 ORB Object adapter Cliente Objeto CORBA  El object adapter se sitúa entre el ORB y el objeto OBJECT ADAPTERS

79 Inicialmente se creó el BOA (basic object adapter) El BOA estaba subespecificado Cada implementador desarrolló sus extensiones, por lo que el BOA dejó de ser interoperable En respuesta a este problema el OMG desarrolló el POA (portable object adpater) El POA está bien estandarizado y es interoperable Actualmente se recomienda usar el POA en lugar del BOA OBJECT ADAPTERS

80 POA: Portable Object Adapter El POA es responsable de:  Crear referencias a objetos  Activar objetos  Despachar las solicitudes que se hacen a los objetos  Desactivar objetos PORTABLE OBJECT ADAPTER

81 ORB clienteORB servidor Solicitud POA Servant Objeto CORBA Referencia de objeto Flujo real de la solicitud Conexión lógica  Mecanismo de despacho de solicitudes PORTABLE OBJECT ADAPTER

82  Mecanismo de despacho de solicitudes ORB POA Manager Solicitudes Servidores (servants) Aplicación servidora PORTABLE OBJECT ADAPTER

83 Algunas definiciones Objeto CORBA. Un ente capaz de recibir solicitudes, realizar operaciones en respuesta a dichas solicitudes y devolver el resultado. Adicionalmente puede tener estado (variables internas). Los solicitudes pueden ser locales o remotas Referencia CORBA. Un bloque de datos que contiene toda la información necesaria para determinar la ubicación de un objeto y poder hacer solicitudes al mismo Clave del objeto (object key). Es una parte de la referencia de un objeto. Identifica al objeto dentro del contexto del ORB donde reside. PORTABLE OBJECT ADAPTER

84 Algunas definiciones ID del objeto (object ID). Es una parte de la clave del objeto. El ID identifica al objeto dentro del contexto del POA que lo maneja Servant. El sirviente es el objeto en el lenguaje de implementación que realiza las operaciones solicitadas al objeto CORBA. Si dicho lenguaje no es orientado a objetos, el sirviente puede ser una estructura de datos con una serie de operaciones asociadas PORTABLE OBJECT ADAPTER

85 Sirviente (servant) Es la unidad de ejecución que encarna al objeto CORBA. Por ejemplo, un objeto en Java o en C++ (También puede ser un proceso). Un objeto CORBA es una entidad conceptual: un ente capaz de recibir solicitudes y... El objeto existe siempre que exista una referencia al mismo Cuando el objeto recibe una solicitud debe ser asociado con un sirviente que realice la tarea (como suelen hacer los sirvientes) PORTABLE OBJECT ADAPTER

86 Cuando el objeto no tiene un sirviente asociado se dice que está inactivo. Cuando se le asocia un sirviente se dice que está activo Activar un objeto consiste en asociarlo a un sirviente Desactivar un objeto consiste en romper la asociación con su sirviente Un mismo sirviente puede ser asociado con varios objetos. Los sirvientes pueden destruirse cuando se desactivan los objetos o pueden permanecer Estas características permiten crear aplicaciones escalables que utilicen eficientemente los recursos de la máquina

87 Ejemplo. Se crea un objeto y se activa al mismo tiempo... // crear el sirviente PozoImpl pozoImpl = new PozoImpl(id); try { // crear la referecia org.omg.CORBA.Object obj = _poa().servant_to_reference(pozoImpl); Pozo pozo = PozoHelper.narrow(obj); return pozo; } catch( SystemException se ) { return null; } catch( UserException ue ){ return null; } PORTABLE OBJECT ADAPTER

88 La activación del objeto puede hacerse : Al momento de crear el objeto. Explícitamente, solicitando al POA que active el objeto. Cuando se reciba una solicitud estando el objeto inactivo. Cada vez que se recibe una solicitud.

89 PORTABLE OBJECT ADAPTER Objeto existe Objeto no existe Objeto activado Objeto desactivado Activar objeto desactivar objeto Crear objeto Crear referencia Destruir

90 El POA es altamente configurable Existen diversas opciones para cada una de las responsabilidades del POA agrupadas en categorías Para manejar las diferentes categorías el POA define lo que se conoce como políticas del POA (POA policies) A continuación se describen algunas de las categorías y las políticas correspondientes PORTABLE OBJECT ADAPTER

91 Política de unicidad del ID Determina si más de un ID de objeto puede referirse al mismo sirviente Posibles valores: UNIQUE_ID y MULTIPLE_ID Valor por defecto: UNIQUE_ID

92 PORTABLE OBJECT ADAPTER Política de asignación del ID Determina si el ID del objeto lo asigna el programador o el POA Posibles valores: USER_ID y SYSTEM_ID Valor por defecto: SYSTEM_ID

93 PORTABLE OBJECT ADAPTER Tiempo de vida Determina si los objetos son transitorios o persistentes. Es decir si los objetos están disponibles después de que el POA haya sido destruido Posibles valores: TRANSIENT y PERSISTENT Valor por defecto: TRANSIENT

94 PORTABLE OBJECT ADAPTER Política de retención de sirvientes Determina si el POA mantiene la asociación entre el ID del objeto y el sirviente en su Mapa de Objetos Activos (Active Object Map) Posibles valores: RETAIN y NON_RETAIN Valor por defecto: RETAIN

95 PORTABLE OBJECT ADAPTER Política de procesamiento de solicitudes Determina que debe utilizar el POA para localizar al sirviente:  Mapa de objetos activos  Default servant  Servant locator o Servant activator Posibles valores: USE_SERVANT_MANAGER, USE_ACTIVE_OBJECT_MAP, USE_DEFAULT_SERVANT Valor por defecto: USE_ACTIVE_OBJECT_MAP

96 Política de hilos (threads). El POA ofrece dos opciones al momento de despachar las solicitudes a los servidores (multithreding policy):  Las solicitudes son colocades en cola y despachadas una a la vez (modelo de un solo hilo de ejecución)  Cada solicitud es ejecutada en un hilo de ejecución separado Posibles valores: ORB_CTRL_MODEL y SINGLE_TREAD_MODEL Valor por defecto: ORB_CTRL_MODEL PORTABLE OBJECT ADAPTER

97 Política de activación implícita Determina si el POA puede activar implícitamente al sirviente al momento de crear el ID del objeto Posibles valores: IMPLICIT_ACTIVATION Y NO_IMPLICIT_ACTIVATION Valor por defecto: NO_IMPLICIT_ACTIVATION (excepto para el rootPOA que permite IMPLICIT_ACTIVATION)

98 PORTABLE OBJECT ADAPTER Es posible que se desee que diferentes objetos utilicen políticas diferentes Cuando se define una política a un POA la misma se aplica a todos los objetos que maneja Sin embargo, se puede crear más de un POA y cada POA puede tener un conjunto diferente de políticas

99 PORTABLE OBJECT ADAPTER Existe un POA inicial llamado RootPOA Si no se requieren conjuntos de políticas diferentes se puede usar el RootPOA para todos los objetos Por el contrario, se pueden crear diferentes POAs y asignar políticas diferentes a cada uno

100 Como crear un POA... // obtener la refencia al rootPOA POA rootPoa = POAHelper.narrow( orb.resolve_initial_references("RootPOA")); // crear un nuevo poa con políticas diferentes org.omg.CORBA.Policy policies[] = new org.omg.CORBA.Policy[4]; policies[0] = rootPoa.create_id_assignment_policy(IdAssignmentPolicyValue.USER_ID); policies[1] = rootPoa.create_lifespan_policy(LifespanPolicyValue.PERSISTENT); policies[2] = rootPoa.create_servant_retention_policy(ServantRetentionPolicyValue. RETAIN); policies[3] = rootPoa.create_request_processing_policy(RequestProcessingPolicyValue, USE_SERVANT_MANAGER); POA myPoa = rootPoa.create_POA("myPOA", rootPoa.the_POAManager(), policies);... PORTABLE OBJECT ADAPTER

101 Ejemplo. Se crea un objeto y se activa al mismo tiempo... // crear el sirviente PozoImpl pozoImpl = new PozoImpl(id); try { // crear la referecia org.omg.CORBA.Object obj = _poa().servant_to_reference(pozoImpl); Pozo pozo = PozoHelper.narrow(obj); return pozo; } catch( SystemException se ) { return null; } catch( UserException ue ){ return null; } PORTABLE OBJECT ADAPTER

102 Asignación de sirvientes: Para determinar cual sirviente utilizar el POA usa una tabla denominada AOM (active object map) Cuando el objeto es activado se agrega una entrada al AOM que asocia el ID del objeto con el sirviente Cuando el objeto es desactivado se elimina la entrada del AOM Es posible configurar el POA para que, en lugar del AOM, invoque a un objeto definido por el usuario para obtener el sirviente La política de procesamiento de solicitudes determina como se hace la asociación entre el objeto y el sirviente PORTABLE OBJECT ADAPTER

103 Asignación de sirvientes: Es posible configurar el POA para que, en lugar del AOM, invoque a un objeto definido por el usuario para obtener el sirviente La política de procesamiento de solicitudes determina como obtiene el POA el sirviente que va a procesar las solicitudes. Los posibles valores son:  USE_ACTIVE_ OBJECT_MAP  USE_DEFAULT_SERVANT  USE_SERVANT_MANAGER PORTABLE OBJECT ADAPTER

104 Cuando el valor de la política es  USE_DEFAULT_SERVANT En este caso el POA usará un único sirviente para todas las solicitudes. El programador debe señalarle al POA cual es el sirviente por defecto:... PozoImpl p = new PozoImpl(1); // crear el sirviente... poa.set_servant(p); // asignar el sirviente // por defecto... PORTABLE OBJECT ADAPTER

105 Cuando el valor de la política es  USE_SERVANT_MANAGER En este caso, cuando un objeto inactivo recibe una solicitud, el POA usará un manejador de sirvientes (servant manager) para obtener el sirviente que se asignará al objeto. Manejador de sirvientes: un objeto que el POA invoca para obtener un sirviente y para destruir el siriviente en caso necesario Hay dos tipos:  Activador de sirvientes (ServantActivator)  Localizador de sirvientes (ServantLocator) PORTABLE OBJECT ADAPTER

106 Activadores de sirvientes: Son invocados cuando se hace una solicitud a un objeto inactivo o cuando el objeto es activado explícitamente mediante una invocación al POA No son invocados cuando un objeto activo recibe solicitudes Cuando el objeto está activo y se recibe una solicitud, el POA usa el AOM para obtener el sirviente PORTABLE OBJECT ADAPTER

107 Activadores de sirvientes: Para usar un activador de sirvientes las siguientes políticas deben estar definidas:  Política de procesamiento de solicitudes:  USE_SERVANT_MANAGER.  Política de retención de sirvientes: RETAIN. Además, será necesario indicarle al POA cual es el manejador de sirvientes: // crear el servant manager y activarlo ActivadorPozos activador = new ActivadorPozos(); pozoPoa.set_servant_manager(activador._this(orb)); PORTABLE OBJECT ADAPTER

108 Localizadores de sirvientes: Son invocados cada vez que se hace una solicitud al objeto En este caso el POA no usa el AOM para localizar el sirviente en ningún momento Para usar un localizador de sirvientes las siguientes políticas deben estar definidas: Política de procesamiento de solicitudes:  USE_SERVANT_MANAGER.  Política de retención de sirvientes: NON_RETAIN También será necesario definir el ServantLocator: // crear el servant manager y activarlo LocalizadorPozos localizador = new LocalizadorPozos(); pozoPoa.set_servant_manager(localizador._this(orb)); PORTABLE OBJECT ADAPTER

109 Ejemplo: una aplicación de objetos persistentes Se presenta una aplicación de pozos que maneja pozos persistentes Los Pozos guardan su estado en un archivo en disco Se usa un ServantActivator para obtener los sirvientes y para leer y escribir el estado de los objetos Se incluye una aplicación de creación de pozos y una aplicación de consulta que pide el ID de un Pozo e imprime los datos del mismo. PORTABLE OBJECT ADAPTER

110 Interfaces module pozos { interface Pozo { string devolverId(); long devolverProduccionCrudo(); long devolverProduccionGas(); void actualizarProduccionCrudo(in long produccion); void actualizarProduccionGas(in long produccion); void desactivar(); }; interface FabricaPozos { Pozo crearPozo(in string id); }; PORTABLE OBJECT ADAPTER

111 Implementación de pozos public class PozoImpl extends PozoPOA { String id; int produccionCrudo; int produccionGas; PozoImpl(String id) { this.id =id; } public String devolverId() { return id; } public int devolverProduccionCrudo() { return produccionCrudo; } public void actualizarProduccionGas(int produccion) { produccionGas = produccion; } PORTABLE OBJECT ADAPTER

112 Implementación de pozos... public void desactivar() { try { _poa().deactivate_object(_poa().servant_to_id(this)); } catch( Exception e ) { } } public void guardarEstado() { try { FileWriter f = new FileWriter("P"+id+".dat"); PrintWriter p = new PrintWriter(f); p.println(produccionCrudo); p.println(produccionGas); p.flush(); } catch (FileNotFoundException e) { } catch (IOException e) { } } PORTABLE OBJECT ADAPTER

113 Implementación de pozos public void leerEstado() { try { FileReader f = new FileReader("P"+id+".dat"); LineNumberReader l = new LineNumberReader(f); produccionCrudo = Integer.parseInt(l.readLine()); produccionGas = Integer.parseInt(l.readLine()); } catch (FileNotFoundException e) { } catch (IOException e) { } } PORTABLE OBJECT ADAPTER

114 Aplicación servidora public class Servidor { public static void main(String[] args) { try { //iniciar el orb ORB orb = ORB.init( args, null ); // iniciar el POA POA rootPoa = POAHelper.narrow( orb.resolve_initial_references("RootPOA")); // crear el poa que manejara los pozos org.omg.CORBA.Policy policies[] = new org.omg.CORBA.Policy[4]; policies[0] = rootPoa.create_id_assignment_policy (IdAssignmentPolicyValue.USER_ID); policies[1] = rootPoa.create_lifespan_policy (LifespanPolicyValue.PERSISTENT); policies[3] = rootPoa.create_request_processing_policy (RequestProcessingPolicyValue.USE_SERVANT_MANAGER); POA pozoPoa = rootPoa.create_POA ("PozoPOA", rootPoa.the_POAManager(), policies); // crear el servant manager y activarlo ActivadorPozos activador = new ActivadorPozos(); pozoPoa.set_servant_manager(activador._this(orb)); PORTABLE OBJECT ADAPTER

115 Aplicación servidora... // crear la fabrica de pozos FabricaPozosImpl f = new FabricaPozosImpl(pozoPoa, orb); // crear la referencia org.omg.CORBA.Object obj = rootPoa.servant_to_reference(f); // escribir la referencia a un archivo FileWriter out = new FileWriter("fabrica.ref"); out.write( orb.object_to_string( obj ) ); out.close(); rootPoa.the_POAManager().activate(); // esperar solicitudes orb.run(); } // capturar excepciones... } PORTABLE OBJECT ADAPTER

116 Implementación del manajador de sirvientes public class ActivadorPozos extends ServantActivatorPOA { public Servant incarnate(byte[] oid, POA adapter) throws ForwardRequest { PozoImpl p = new PozoImpl(new String(oid)); p.leerEstado(); return p; } public void etherealize(byte[] oid, POA adapter, Servant serv, boolean cleanup_in_progress, boolean remaining_activations) { PozoImpl p = (PozoImpl) serv; p.guardarEstado(); } PORTABLE OBJECT ADAPTER

117 Aplicación de crear pozos public class CrearPozo { public static void main(String args[]) { try { // iniciar el ORB ORB orb = ORB.init( args, null ); // leer la referencia de la fabrica de pozos String ior = new BufferedReader( new FileReader("fabrica.ref")).readLine(); org.omg.CORBA.Object obj = orb.string_to_object( ior ); FabricaPozos f = FabricaPozosHelper.narrow( obj ); // verificar si la referencia era del tipo correcto if( f == null ) { System.err.println("Error, referencia invalida"); System.exit( 1 ); } PORTABLE OBJECT ADAPTER

118 Aplicación de crear pozos InputStreamReader r = new InputStreamReader(System.in); LineNumberReader l = new LineNumberReader(r); // pedir datos al usuario System.out.print("id del pozo: "); String id = l.readLine(); System.out.print("Producción de crudo: "); int prodCrudo = Integer.parseInt(l.readLine()); System.out.print("Producción de gas: "); int prodGas = Integer.parseInt(l.readLine()); // crear el pozo Pozo p = f.crearPozo(id); p.actualizarProduccionCrudo(prodCrudo); p.actualizarProduccionGas(prodGas); // escribir la referencia a un archivo FileWriter out = new FileWriter("p"+id+".ref"); out.write( orb.object_to_string( p ) ); out.close(); p.desactivar(); } // capturar excepciones PORTABLE OBJECT ADAPTER

119 Ejercicio no. 4. Implemente la aplicación de objetos persistentes presentada en esta sección. Siga los siguientes pasos: 1.Agregue los métodos GuardarEstado y LeerEstado a la clase PozoImpl. 2.Implemente la clase ActivadorPozos. 3.Implemente una clase CreadorPozos que pida al usuario los datos del pozo e invoque la fábrica para crear el pozo. 4.Implemente una clase Consulta que pida el id del pozo, lea la refencia de un archivo cuyo nombre es el ID del pozo e imprima los datos del mismo. 5.Utilice la clase Servidor suministrada para probar la aplicación.

120 SERVICIOS CORBA

121 Los servicios CORBA son una colección de interfaces y objetos que soportan funciones básicas para el uso y la implementación de objetos Estos servicios son necesarios para desarrollar cualquier aplicación y son independientes de cualquier aplicación particular Por ejemplo el servicio de nombres permite registrar referencias CORBA con un nombre y retribuir las referencias Los servicios son objetos CORBA

122 SERVICIOS CORBA Algunos de los servicios más importantes: Nombres (Naming) Notificación (Notification) Persistencia (Persistent Object) Transacciones (Transaction)

123 Servicio de nombres El servicio de nombres (name service) es un directorio de objetos CORBA El servicio de nombres de CORBA permite:  Asociar nombres con objetos CORBA (registrar un objetos en el servicio de nombres)  Dado el nombre de un objeto, obtener su referencia Si se conoce el nombre con el que un objeto está registrado se puede obtener su referencia haciendo una consulta al servicio de nombres (similar a un directorio telefónico) SERVICIOS CORBA

124 Organización del servicio de nombres  El servicio de nombres consiste en una colección de objetos CORBA llamados NamingContext (Contexto de nombres)  Un NamingContext es un objeto CORBA que almacena pares (nombre, objeto), denominados bindings  Un NamingContext puede contener otros NamingContext s, lo cual permite crear estructuras jerárquicas o grafos SERVICIOS CORBA

125  Servicio de nombres de CORBA Root context Fabrica de Pozos Pozos de flujo natural Pozos de gas lift Pozos BES p128 p129 p200 p500 Naming contex Objetos finales SERVICIOS CORBA

126 Uso del servicio de nombres Se debe ejecutar el servidor de nombres El servidor de nombres crea un contexto vacío denominado rootContext Para acceder al root context se usa la operación resolve_initial_references org.omg.CORBA.Object root = orb.resolve_initial_references("NameService"); NamingContextExt rc = NamingContextExtHelper.narrow(root); SERVICIOS CORBA

127 Uso del servicio de nombres Para registrar un objeto en el root context (o en cualquier otro contexto) se usa la operación bind // registrar un pozo en el servicio de nombres Pozo p;... String id = p.devolverId(); rc.bind(rc.to_name(id), p); SERVICIOS CORBA

128 Uso del servicio de nombres Para crear un nuevo contexto de nombres dentro de otro se usa la operación bindNewContext. // crear un contexto dentro de otro contexto rc.bind_new_context(rc.to_name("Pozos")); Para registrar objetos dentro del contexto Pozos se puede obtener su referencia y luego usar la operación bind. // obtener el contexto de pozos org.omg.CORBA.Object obj = rc.resolve(rc.to_name("Pozos")); NamingContextExt pozos=NamingContextExtHelper.narrow(obj); // registrar un pozo Pozo p;... pozos.bind(rc.to_name("104"), p); También es posible registrar el nuevo Pozo mediante el root context: rc.bind(rc.to_name("Pozos/104"), p); SERVICIOS CORBA

129 Uso del servicio de nombres Para resolver un nombre se usa la operación resolve. // obtener la referencia del pozo en el servicio nombres String id = "104"; org.omg.CORBA.Object obj = rc.resolve(rc.to_name("Pozos/"+id)); // hacer el narrow a Pozo Pozo p = PozoHelper.narrow( obj ); SERVICIOS CORBA

130 Ejemplo: aplicación de pozos con servicio de nombres Se presenta una aplicación de pozos que maneja pozos persistentes La aplicación servidora guarda la referencia de la fábrica de pozos en el root context Adicionalmente crea un contexto ¨Pozos¨ donde se registrarán todos los pozos creados Se incluye una aplicación de reporte que lista el contenido del contexto ¨Pozos¨ SERVICIOS CORBA

131 Ejemplo: aplicación de pozos con servicio de nombres import org.omg.CosNaming.*; import org.omg.CosNaming.NamingContextPackage.*; public class Servidor { public static void main(String[] args) { try { //iniciar el orb ORB orb = ORB.init( args, null ); // iniciar el POA POA rootPoa = POAHelper.narrow( orb.resolve_initial_references("RootPOA")); // crear el poa que manejara los pozos org.omg.CORBA.Policy policies[] = new org.omg.CORBA.Policy[4]; policies[0] = rootPoa.create_id_assignment_policy (IdAssignmentPolicyValue.USER_ID); policies[1] = rootPoa.create_lifespan_policy (LifespanPolicyValue.PERSISTENT); policies[2] = rootPoa.create_servant_retention_policy (ServantRetentionPolicyValue.RETAIN); SERVICIOS CORBA

132 Ejemplo: aplicación de pozos con servicio de nombres policies[3] = rootPoa.create_request_processing_policy (RequestProcessingPolicyValue.USE_SERVANT_MANAGER); POA pozoPoa = rootPoa.create_POA("PozoPOA", rootPoa.the_POAManager(), policies); // crear el servant manager y activarlo ActivadorPozos activador = new ActivadorPozos(); pozoPoa.set_servant_manager(activador._this(orb)); // crear la fabrica de polinomios FabricaPozosImpl f = new FabricaPozosImpl(pozoPoa, orb); org.omg.CORBA.Object obj = rootPoa.servant_to_reference(f); // registrar la referencia en el servicio de nombres org.omg.CORBA.Object r = orb.resolve_initial_references("NameService"); NamingContextExt rc = NamingContextExtHelper.narrow(r); rc.bind(rc.to_name("Fabrica de pozos"), obj); //crear el contexto que contendrá las referencias de los pozos rc.bind_new_context(rc.to_name("Pozos")); rootPoa.the_POAManager().activate(); // esperar solicitudes orb.run(); } SERVICIOS CORBA

133 Ejemplo: aplicación de pozos con servicio de nombres public class CreadorPozos { public static void main(String args[]) { try { // iniciar el ORB ORB orb = ORB.init( args, null ); // obtener la referencia de la fabrica de pozos //en el servicio de nombres org.omg.CORBA.Object root = orb.resolve_initial_references("NameService"); NamingContextExt rc = NamingContextExtHelper.narrow(root); org.omg.CORBA.Object obj = rc.resolve(rc.to_name("Fabrica de pozos")); FabricaPozos f = FabricaPozosHelper.narrow( obj ); // verificar si la referencia era del tipo correcto if( f == null ) { System.err.println("Error, referencia inválida"); System.exit( 1 ); } SERVICIOS CORBA

134 Ejemplo: aplicación de pozos con servicio de nombres // verificar si la referencia era del tipo correcto if( f == null ) { System.err.println("Error, referencia invalida"); System.exit( 1 ); } InputStreamReader r = new InputStreamReader(System.in); LineNumberReader l = new LineNumberReader(r); // pedir datos al usuario System.out.print("id del pozo: "); String id = l.readLine(); System.out.print("Producción de crudo: "); int prodCrudo = Integer.parseInt(l.readLine()); System.out.print("Producción de gas: "); int prodGas = Integer.parseInt(l.readLine()); // crear el pozo Pozo p = f.crearPozo(id); p.actualizarProduccionCrudo(prodCrudo); p.actualizarProduccionGas(prodGas); // registrar el pozo en el servicio de nombres rc.bind(rc.to_name("Pozos/"+id), p); p.desactivar(); } //capturar excepciones SERVICIOS CORBA

135 Ejemplo: aplicación de pozos con servicio de nombres public class Consulta { public static void main(String args[]) { try { // iniciar el ORB ORB orb = ORB.init( args, null ); // obtener la referencia del servicio de nombres org.omg.CORBA.Object root = orb.resolve_initial_references("NameService"); NamingContextExt rc = NamingContextExtHelper.narrow(root); InputStreamReader r = new InputStreamReader(System.in); LineNumberReader l = new LineNumberReader(r); System.out.print("Id del pozo: "); String id = l.readLine();... SERVICIOS CORBA

136 Ejemplo: aplicación de pozos con servicio de nombres... // obtener la referencia del pozo en el servicio nombres org.omg.CORBA.Object obj = rc.resolve(rc.to_name("Pozos/"+id)); // hacer el narrow a Pozo Pozo p = PozoHelper.narrow( obj ); // verificar si la referencia era del tipo correcto if( p == null ) { System.out.println("Error, el pozo "+id+" no existe"); System.exit( 1 ); } int prodCrudo = p.devolverProduccionCrudo(); int prodGas = p.devolverProduccionGas(); System.out.println("Producción de crudo: " + prodCrudo); System.out.println("Producción de gas: " + prodGas); p.desactivar(); } SERVICIOS CORBA

137 La operación list devuelve el contenido de un contexto de nombres try { BindingListHolder listHolder = new BindingListHolder(); BindingIteratorHolder iteratorHolder = new BindingIteratorHolder(); // obtener la lista de pozos pozos.list(0, listHolder, iteratorHolder); BindingIterator iterator = iteratorHolder.value; BindingHolder bindingHolder = new BindingHolder(); // recorrer la lista e imprimir cada pozo System.out.println("ID Prod. crudo Prod. gas"); while (iterator.next_one(bindingHolder)) { Binding binding = bindingHolder.value; NameComponent[] id = binding.binding_name; obj = pozos.resolve(id); Pozo p = PozoHelper.narrow(obj); System.out.println(p.devolverId()+" "+ p.devolverProduccionCrudo()+" "+ p.devolverProduccionGas()); } } catch (UserException ex) { System.out.println(ex); } SERVICIOS CORBA

138 Ejercicio no. 5. Modifique la aplicación de pozos para que, en lugar de guardar referencias en disco utilice el servicio de nombres CORBA para registrar la referencia de la fábrica de pozos y los pozos creados.

139 Ejercicio no. 6. Implemente una aplicación que produzca un listado de los pozos registrados en el contexto “Pozos” de la aplicación implementada en el ejercicio anterior.

140 Ejercicio no. 7. Modifique la aplicación de pozos para que incluya las interfaces PozoGasLift y PozoBES definidas en la sección 4.4. Siga los siguientes pasos: 1.Agregue a la interfaz Pozo el método string toString() que devuelve un string con la información del Pozo (id, tipo y producción). 2.Implemente los tipos PozoBES y PozoGasLift. 3.Defina un tipo enumerado TipoPozo que tenga los valores: PozoBES y PozoGasLift. 4.Modifique la fábrica de pozos para que tome como parámetro adicional el tipo de pozo requerido y cree el pozo del tipo correspondiente. 5.Modifique la aplicación de crear pozos para que pida al usuario el tipo de pozo y cree el pozo correspondiente. 6.Modifique la aplicación de reporte para que imprima la información de los diferentes tipos de Pozo.


Descargar ppt "PROCESAMIENTO DISTRIBUIDO UTILIZANDO CORBA Universidad del Zulia Facultad de Ingeniería Instituto de Cálculo Aplicado Prof. Carlos Arévalo, M.Sc."

Presentaciones similares


Anuncios Google