Grupo de Arquitectura de Computadores, Comunicaciones y Sistemas Desarrollo de Aplicaciones Distribuidas AUTORES: Alejandro Calderón Mateos Javier García Blas David Expósito Singh Laura Prada Camacho Departamento de Informática Universidad Carlos III de Madrid Julio de 2012 JAVA RMI: CALLBACK DE CLIENTE Contenidos Introducción: 1. 1. Callback de cliente Callback de cliente en Java RMI 2. 1. 2. Arquitectura del sistema Elementos a desarrollar Ajustes en desarrollo y despliegue 3. 1. 2. 2 Descarga del resguardo Políticas de seguridad Contenidos Introducción: 1. 1. Callback de cliente Callback de cliente en Java RMI 2. 1. 2. Arquitectura del sistema Elementos a desarrollar Ajustes en desarrollo y despliegue 3. 1. 2. 3 Descarga del resguardo Políticas de seguridad Callback de cliente Servidor } Clientes C1 En el modelo cliente-servidor el servidor es pasivo C2 C3 C4 C5 Llamadas RMI 4 } El cliente pide un servicio y el servidor devuelve unos resultados como respuesta en un plazo de tiempo Callback de cliente Servidor Clientes ¨ C1 C2 ¿Qué pasa cuando el cliente quiere una o varias respuestas de forma asíncrona? C3 C4 C5 Llamadas RMI 5 ¨ Ejemplo: apuntarse para ser informados de los cambios en la bolsa Callback de cliente ¨ Servidor Alternativas: Clientes C1 Lista de callback C2 C3 C4 C5 ¤ Polling n Preguntar cada cierto tiempo n Peticiones sin cambios causan sobrecarga ¤ Callback n Registrarse Llamadas RMI callback 6 en el servidor para que nos avise ante los eventos Contenidos Introducción: 1. 1. Callback de cliente Callback de cliente en Java RMI 2. 1. 2. Arquitectura del sistema Elementos a desarrollar Ajustes en desarrollo y despliegue 3. 1. 2. 7 Descarga del resguardo Políticas de seguridad Arquitectura de RMI (no callback) Servicio de directorios Cliente de objetos Servidor de objetos stub skeleton Referencia remota Referencia remota Transporte Transporte Ruta de datos lógica Ruta de datos física 8 Arquitectura de RMI (callback) Servicio de directorios Cliente de Servidor de objetos objetos stub Referencia remota Transporte Skeleton stub skeleton Referencia remota Transporte Servidor invoca método callback del cliente Cliente invoca método remoto del servidor 9 Contenidos Introducción: 1. Callback de cliente 1. Callback de cliente en Java RMI 2. Arquitectura del sistema Elementos a desarrollar 1. 2. Ajustes en desarrollo y despliegue 3. 1. 2. 10 Descarga del resguardo Políticas de seguridad Invocación remota (no callback) Cliente de objetos Servidor de objetos Client.class Server.class Interface.class Interface.class Impl.class Stub.class 11 Skel.class Invocación remota (callback) Cliente de objetos Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class 12 Servidor de objetos ServerImpl.class ServerImpl _Stub.class ClientImpl _Stub.class ClientImpl _ skel.class ServerImpl _skel.class Invocación remota (callback) } Cliente de objetos Servidor de objetos Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class ServerImpl.class ServerImpl_Stub.class ClientImpl_Stub.class ClientImpl_skel.class ServerImpl_skel.class Los clientes se registran como servidor de objeto remoto para callbacks. } Dos conjuntos de proxies. } Piezas clave: } } 13 Interface remota de cliente. Servicio de registro de interfaces de cliente en servidor Cliente de objetos ClientInterface.java o Interfaz remota del cliente o Debe contener, al menos, un método para ser invocado por el servidor Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class ServerImpl.class ServerImpl_Stub.class ClientImpl_Stub.class ClientImpl_skel.class ServerImpl_skel.class import java.rmi.*; public interface ClientInterface extends java.rmi.Remote { public String notifyMe ( String message ) throws java.rmi.RemoteException ; } 14 Servidor de objetos Cliente de objetos ClientImpl.java o Implementación de la Interfaz remota del cliente o Generación the proxies con rmic ClientImpl Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class ServerImpl.class ServerImpl_Stub.class ClientImpl_Stub.class ClientImpl_skel.class ServerImpl_skel.class import java.rmi.*; import java.rmi.server.*; public class ClientImpl extends UnicastRemoteObject implements ClientInterface { public ClientImpl() throws RemoteException { super( ); } public String notifyMe ( String message ) { String returnMessage = "Call back received: " + message; System.out.println(returnMessage); return returnMessage; } } 15 Servidor de objetos Cliente de objetos Client.java (1/3) import java.io.*; import java.rmi.*; Servidor de objetos Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class ServerImpl.class ServerImpl_Stub.class ClientImpl_Stub.class ClientImpl_skel.class ServerImpl_skel.class public class Client { public static void main(String args[]) { try { InputStreamReader is = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(is); System.out.println("Enter the RMIRegistry host namer:"); String hostName = br.readLine(); System.out.println("Enter the RMIregistry port number:"); String portNum = br.readLine(); System.out.println("Enter how many seconds to stay registered:"); String timeDuration = br.readLine(); int time = Integer.parseInt(timeDuration); 16 Cliente de objetos Client.java (2/3) Servidor de objetos Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class ServerImpl.class ServerImpl_Stub.class ClientImpl_Stub.class ClientImpl_skel.class ServerImpl_skel.class String regURL = "rmi://" + hostName + “:" + portNum + "/callback"; ServerInterface h = (ServerInterface)Naming.lookup(regURL); System.out.println("Lookup completed “); System.out.println("Server said " + h.sayHello()); ClientInterface callbackObj = new ClientImpl(); h.registerForCallback(callbackObj); System.out.println("Registered for callback."); 17 Cliente de objetos Client.java (3/3) Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class ServerImpl.class ServerImpl_Stub.class ClientImpl_Stub.class ClientImpl_skel.class ServerImpl_skel.class try { Thread.sleep(time * 1000); h.unregisterForCallback(callbackObj); System.out.println("Unregistered for callback."); } catch (InterruptedException ex){ /* sleep over */ } } // try catch (Exception e) { System.out.println("Exception in CallbackClient: " + e); } } // main } // class 18 Servidor de objetos Cliente de objetos ServerInterface.java o Extensión en la parte servidora o Método remoto de registro del cliente para callback import java.rmi.*; public interface ServerInterface extends Remote { public String sayHello( ) throws java.rmi.RemoteException; public void registerForCallback( ClientInterface callbackClientObject ) throws java.rmi.RemoteException; public void unregisterForCallback( ClientInterface callbackClientObject ) throws java.rmi.RemoteException; } 19 Servidor de objetos Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class ServerImpl.class ServerImpl_Stub.class ClientImpl_Stub.class ClientImpl_skel.class ServerImpl_skel.class Cliente de objetos ServerImpl.java (1/4) Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class ServerImpl.class ServerImpl_Stub.class ClientImpl_Stub.class ClientImpl_skel.class ServerImpl_skel.class import java.rmi.*; import java.rmi.server.*; import java.util.Vector; public class ServerImpl extends UnicastRemoteObject implements ServerInterface { private Vector clientList; public ServerImpl() throws RemoteException { super( ); clientList = new Vector(); } public String sayHello( ) throws RemoteException { return("hello"); } 20 Servidor de objetos Cliente de objetos ServerImpl.java (2/4) Servidor de objetos Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class ServerImpl.class ServerImpl_Stub.class ClientImpl_Stub.class ClientImpl_skel.class ServerImpl_skel.class public synchronized void unregisterForCallback ( ClientInterface callbackClientObject ) throws RemoteException { if (clientList.removeElement(callbackClientObject)) { System.out.println("Unregistered client. "); } else { System.out.println("unregister: client wasn't registered."); } } 21 Cliente de objetos ServerImpl.java (3/4) Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class ServerImpl.class ServerImpl_Stub.class ClientImpl_Stub.class ClientImpl_skel.class ServerImpl_skel.class public synchronized void registerForCallback( ClientInterface callbackClientObject ) throws RemoteException { if (!(clientList.contains(callbackClientObject))) { clientList.addElement(callbackClientObject); doCallbacks(); } } 22 Servidor de objetos Cliente de objetos ServerImpl.java (4/4) Servidor de objetos Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class ServerImpl.class ServerImpl_Stub.class ClientImpl_Stub.class ClientImpl_skel.class ServerImpl_skel.class private synchronized void doCallbacks( ) throws RemoteException { for (int i = 0; i < clientList.size(); i++) { System.out.println("doing "+ i +"-th callback\n"); ClientInterface nextClient = (ClientInterface) clientList.elementAt(i); nextClient.notifyMe("Number of registered clients=" + clientList.size()); } // for } // function } // class 23 Cliente de objetos Server.java (1/3) import import import import import import Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class ServerImpl.class ServerImpl_Stub.class ClientImpl_Stub.class ClientImpl_skel.class ServerImpl_skel.class java.rmi.*; java.rmi.server.*; java.rmi.registry.Registry; java.rmi.registry.LocateRegistry; java.net.*; java.io.*; public class Server { public static void main(String args[]) { InputStreamReader is = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(is); 24 Servidor de objetos Cliente de objetos Server.java (2/3) Servidor de objetos Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class ServerImpl.class ServerImpl_Stub.class ClientImpl_Stub.class ClientImpl_skel.class ServerImpl_skel.class String portNum, registryURL; try { System.out.println("Enter the RMIregistry port number:"); portNum = (br.readLine()).trim(); int RMIPortNum = Integer.parseInt(portNum); startRegistry(RMIPortNum); ServerImpl exportedObj = new ServerImpl(); registryURL = "rmi://localhost:" + portNum + "/callback"; Naming.rebind(registryURL, exportedObj); System.out.println("Callback Server ready."); } catch (Exception re) { System.out.println("Exception in HelloServer.main: " + re); } } // end main 25 Cliente de objetos Server.java (3/3) Servidor de objetos Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class ServerImpl.class ServerImpl_Stub.class ClientImpl_Stub.class ClientImpl_skel.class ServerImpl_skel.class private static void startRegistry (int RMIPortNum) throws RemoteException { try { Registry registry = LocateRegistry.getRegistry(RMIPortNum); registry.list( ); } catch (RemoteException e) { // No valid registry at that port. Registry registry = LocateRegistry.createRegistry(RMIPortNum); } } // end startRegistry } // end class 26 Compilación del ejemplo guernika.lab.inf.uc3m.es Cliente de objetos Servidor de objetos Client.class Server.class ClientInterface.class ServerInterface.class ServerInterface.class ClientInterface.class ClientImpl.class ServerImpl.class ServerImpl_Stub.class ClientImpl_Stub.class ClientImpl_skel.class ServerImpl_skel.class # javac -cp /usr/lib/jvm/java-1.4.2-gcj-4.1-1.4.2.0/jre/lib/rt.jar \ -g ClientInterface.java ClientImpl.java # rmic ClientImpl # javac -cp /usr/lib/jvm/java-1.4.2-gcj-4.1-1.4.2.0/jre/lib/rt.jar -g *.java 27 Ejecución del ejemplo guernika.lab.inf.uc3m.es # rmiregistry 9090 & # java -Djava.security.policy=policy.all Server Enter the RMIregistry port number: 9090 Callback Server ready. ^Z # bg # java -Djava.security.policy=policy.all Client Enter the RMIRegistry host namer: localhost Enter the RMIregistry port number: 9090 Enter how many seconds to stay registered: 60 Lookup completed Server said hello doing 0-th callback Call back received: Number of registered clients=1 Registered for callback. … 28 Contenidos Introducción: 1. Callback de cliente 1. Callback de cliente en Java RMI 2. Arquitectura del sistema Elementos a desarrollar 1. 2. Ajustes en desarrollo y despliegue 3. 1. 2. 29 Descarga del resguardo Políticas de seguridad Descarga del resguardo ¨ ¨ Objetivo: eliminar la necesidad de que el cliente deba tener el stub. El stub es descargado dinámicamente desde un servidor web. ¨ Es necesario conocer la URL del servidor. ¨ La clase resguardo no es persistente. 30 ARCOS @ UC3M Descarga del resguardo Servidor Cliente Client.class 1 2 3 RMI registry Servidor HTTP SomeInterface _ stub.class 4 SomeInterface_stub.class SomeInterface_skel.class SomeServer.class 31 Gestor de seguridad (por defecto) ¨ Security Manager ¨ Supervisión del programa: ¤ ¤ Acceso a ficheros Conexiones de red Nivel de seguridad inicial: ¨ ¤ ¤ 32 Únicamente conexiones locales. No es posible la transferencia del resguardo. Gestor de seguridad RMI Es posible usar una gestor de seguridad que configurado adecuadamente permita la descarga del resguardo. ¨ ¤ Clase RMISecurityManager ¤ Fichero de política de seguridad 33 ARCOS @ UC3M Gestor de seguridad RMI ¨ Inicio del servicio de seguridad: try { System.setSecurityManager( new RMISecurityManager()); } catch { //… } 34 n Añadir el anterior fragmento de código tanto al programa principal (main) del cliente como del servidor. n Usar antes de utilizar los servicios del registro RMI. Gestor de seguridad RMI ¨ Ejemplo de fichero de políticas de seguridad: grant { permission java.net.SocketPermission "*:1024-65535", "connect,accept,resolve"; permission java.net.SocketPermission "*:80", "connect"; } ; 35 Gestor de seguridad RMI ¨ Ejemplo de despliegue de políticas de seguridad: Java –Djava.rmi.server.codebase=<http://...URL> -­‐Djava.rmi.server.hostname=<nombre servidor> -­‐Djava.security.policy=<ruta completa al fichero de política de seguridad> 36 Resguardos y gestor de seguridad RMI 1. 2. 3. 4. 5. 6. 7. 8. 9. Crear directorio Definir interfaz remoto. Realizar su implementación. Generar ficheros resguardo y esqueleto. Diseñar programa servidor. Copiar fichero resguardo al servidor HTTP. Activar registro RMI. Construir fichero de políticas de seguridad. Activar servidor. 37 Resguardos y gestor de seguridad RMI Cliente Servidor SomeClient.class SomeServer.class SomeInterface.class SomeInterface.class java.policy SomeImplementation.Skeleton.class SomeImplementation.class java.policy Servidor HTTP SomeImplementation_stub 38