Práctica 5: Common Object Request Broker Architecture CORBA Aplicaciones Telemáticas II Introducción El objetivo de esta práctica es entender mejor el funcionamiento de CORBA (Common Object Request Broker Architecture). Para esto comenzaremos desarrollando una sencilla aplicación en CORBA, un servidor de fechas tal como lo hemos hecho en las prácticas de RPC y RMI. CORBA es una arquitectura estándar para el desarrollo de sistemas de objetos distribuidos. Permite realizar llamadas a objetos remotos, independiente del lenguaje de programación en que fueron programados. CORBA es una especificación, no es un software o aplicación. Hay muchas implementaciones de CORBA las cuales son conocidas como ORB (Object Request Broker). Existe una interfaz entre aplicaciones clientes y servidores. Un lenguaje de definición de interfaz (IDL) ha sido definido específicamente para CORBA. Al igual que en RMI una aplicación publica un objeto en el servidor ORB (Object Request Broker) el cual corresponde a un servicio distribuido que implementa el request del objeto remoto y entrega una referencia al objeto a las aplicaciones que lo piden. En esta práctica utilizaremos la implementacin de CORBA para Java. Ejemplo Al igual que en prácticas pasadas implementaremos un servidor de fechas utilizando CORBA, para el lenguaje Java. Primero debemos definir la interfaz con los métodos que serán implementados por el servidor. Para esto utilizaremos el lenguaje IDL. module FechaApp { interface Fecha { string getfecha(); ; 1
; Ahora debemos ejecutar el siguiente comando: > idlj -fall fecha.idl Esto generará el directorio FechaApp y dentro de este, los siguientes ficheros: FechaOperations.java: interfaz que define los métodos a implementar por el servidor. Fecha.java: interfaz que extiende de FechaOperations. FechaPOA.java: clase abstracta que sirve de base para la clase que implementa la interfaz Fecha. FechaHelper.java: clase utilizada por el cliente que le permite acceder a las funciones del ORB. FechaHolder.java: clase que se utiliza para pasar objetos del tipo Fecha como parámetros. FechaStub.java: clase que permite al cliente invocar las operaciones del objeto remoto. Implementación del servidor Debemos crear una nueva clase que implemente los métodos del servidor, esta clase la llamaremos FechaImpl.java. Esta clase debe extender la clase FechaPOA e implementar los métodos definidos en la interfaz Fecha. import org.omg.corba.orb; import java.util.*; class FechaImpl extends FechaPOA { public String getfecha() { return (new Date()).toString(); Ahora la clase correspondiente al servidor, que corresponde a un main el cual debe realizar las siguientes funciones: inicializar el ORB y el POA. crear los objetos CORBA, corresponden a los objetos remotos. pasar el control al ORB. 2
import FechaApp.*; import org.omg.corba.*; import org.omg.portableserver.poahelper; import org.omg.portableserver.poa; import java.util.*; import java.io.*; import org.omg.cosnaming.*; import org.omg.cosnaming.namingcontextpackage.*; import org.omg.corba.*; public class FechaServer { public static void main(string args[]) { try { // crear e inicializar ORB ORB orb = ORB.init(args, null); // crear un objeto remoto FechaImpl impl = new FechaImpl(); // obtener referencia rootpoa y activar el POAManager POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); rootpoa.the_poamanager().activate(); // obtener una referencia al objeto remoto org.omg.corba.object ref = rootpoa.servant_to_reference(impl); Fecha href = FechaHelper.narrow(ref); // las siguientes lineas me permiten publicar un obj remoto org.omg.corba.object objref = orb.resolve_initial_references("nameservice"); NamingContextExt ncref = NamingContextExtHelper.narrow(objRef); // nombre con el cual voy a publicar mi objeto String nombre = "Fecha"; NameComponent path[] = ncref.to_name(nombre); // publicar el objeto ncref.rebind(path, href); // ejecutar el orb orb.run(); catch (Exception e) { System.err.println("ERROR: " + e); Explicación del código: Como cada cliente, el servidor debe crear una instancia de un objeto ORB, de manera de poder publicar el objeto que será llamado de manera remota. Para hacer esto se incluye la siguiente línea: ORB orb = ORB.init(args, null); El servidor corresponde a un programa capaz de crear instancias de uno o más objetos remotos, luego en el servidor debemos crear estos objetos. 3
FechaImpl fechaimpl = new FechaImpl(); Tal como en RMI, para que el objeto sea visible desde otras aplicaciones es necesario publicarlo, para esto es necesario utilizar la clase NamingContextExt. El cliente quedaría implementado de la siguiente manera: import FechaApp.*; import org.omg.corba.*; import org.omg.cosnaming.*; import org.omg.cosnaming.namingcontextpackage.*; public class FechaClient { public static void main(string args[]) { try { // crear e inicializar ORB ORB orb = ORB.init(args, null); // obtener una referencia a NameService org.omg.corba.object objref = orb.resolve_initial_references("nameservice"); // las siguientes lineas nos permiten obtener una ref a un objeto remoto NamingContextExt ncref = NamingContextExtHelper.narrow(objRef); // nombre del obj remoto String nombre = "Fecha"; Fecha impl = FechaHelper.narrow(ncRef.resolve_str(nombre)); System.out.println("Fecha: " + impl.getfecha()); catch (Exception e) { System.out.println("ERROR : " + e); e.printstacktrace(system.out); Al igual que en el servidor, debemos crear un objeto orb y desde el obtener un objeto NamingContextExt para poder obtener la referencia al objeto publicado por el servidor. Finalmente para ejecutar nuestro programa debemos ejecutar el ORB, para esto necesitamos el siguiente comando: > orbd -ORBInitialPort 2500 Ejecutar el servidor: > java FechaServer -ORBInitialPort 2500 Ejecutar el cliente: > java FechaClient -ORBInitialPort 2500 4
Ejercicio 1 Implemente el servidor/cliente de fechas. Ejercicio 2 Al igual que en RPC, para agregar tipos definidos por el usuario es necesario definir un struct. Por ejemplo, si queremos definir un objeto que implemente los siguientes métodos: Circulo calculararea(double) El fichero idl será el siguiente: module EjemploApp { struct Circulo{ double radio; ; interface Ejemplo { Circulo calculararea(in double a); La palabra in antes de double a, define el paso de parámetros para los métodos: in: el parámetro lo entrega el cliente al servidor. out: es retornado por el servidor al cliente. Es decir, el servidor asigna valores a esta variable. inout: el cliente entrega valores y además el servidor asigna valores. En el ejercicio 2, se realizará una implementación simple del juego Master Mind. La idea es que el servidor reciba por línea de comando la combinación a adivinar, en este caso el juego consistirá en adivinar un string de 5 letras. Las letras no se repetiran dentro de la cadena a aadivinar. El servidor deberá implementar los siguientes métodos: Resultado revisarjugada(string s) int numerojugadas() 5
Donde Resultado corresponde a un tipo de dato que nos permite guardar el resultado que entrega el juego, la idea es que almacene el numero de weak matches y strong matches. Un weak match corresponde cuando alguno de los caracteres de la cadena ingresada por el jugador esta dentro de la cadena a adivinar pero en otra posición. Un strong match corresponde cuando el caracter en la cadena ingresada esta en la misma posición que en la cadena a adivinar. Ejemplo, si la cadena a adivinar es FIODA y el usuario ingresa DIOLA el resultado sería: weak matches = 1, el caracter D esta en FIODA pero no en la posición 0. strong matches = 3, los caracteres I, O y A estan en FIODA y en la misma posición. El cliente deberá implementar el siguiente dialogo (utilizando el mismo ejemplo): > KIOLA > Numero de weak matches = 0 > Numero de strong matches = 3 > Numero de jugadas = 1 > > DIOLA > Numero de weak matches = 1 > Numero de strong matches = 3 > Numero de jugadas = 2... > GIOL > Error, el largo de la cadena es 5!! > FIODA > Felicitaciones!!! Entrega Debe entregar todos los archivos generados, a través de la sección de Prácticas del Aula Global en un fichero comprimido, con el nombre NIA P5.zip, antes de las 24:00 del miércoles 21 de febrero. 6