Вы находитесь на странице: 1из 23

Prctica laboratorio

Sistemas Distribuidos curso 2014/2015

Nombre : Gustavo Javier


Apellidos : Rey LLama
DNI
: 49067854E
e-mail
: gusking2006@hotmail.com

Descripcin trabajo realizado


Para afrontar la realizacin de la prctica realic una prueba anterior basndome en la descripcin
dada para comprender el funcionamiento de la misma y para tener un primer contacto con los
callbacks. Para ello utilic material que encontr por interner sobre todo de la pgina de pgina
Oracle de soporte de java y varios sitios ms. Adems del ejemplo que aparece en el libro
Distributed Computing - Concepts and application by profesor M.L.Liu en el sitio
http://www2.cs.uic.edu/~i441/RMICallback/
Habiendo realizado esta proto prctica con ms funciones que las que se nos pide en la prctica
comenc a realizar la prctica pedida.
Teniendo la experincia anterior en cuanto a la publicacin de los servicios, la creacin del registry,
asignacin de puertos para las publicaciones de puertos y dems, comenc con una estructura bsica
y cree las clases que se nos piden para tal fin.
Esta estructura bsica solo implementaba el registro de un usuario.
Para ello tuve que crear a los actores involucrados: el usuario, el servidor y la base de datos con sus
respectivas conexiones a travs del registry.
A medida que todo fue funcionando fui agregando ms funcionalidades hasta llegar a la prctica
final, pero teniendo por el camino muchos problemas que resolver.
Mi prctica consta de las clases obligatorias y algunas ms.

Clases creadas por mi


Archivador: clase que encapsula los datos de los usuarios
Codebase: clase que establece la propiedad codebase
Mensaje: clase que crea mensajes
Menus: clase que escribe menus por pantalla
Seguidores: clase que encapsula la lista de seguidores de cada usuario
Seguridad: clase que establece la propiedad de seguridad

Descripcin de cada clase


Archivador
Implementa Serializable
Clase que encapsula los datos de los usuarios
Sus campos son :
nombre del usuario
*mail
*password
*estado
*indiceTrino lista de mis mensajes: es un arraylist donde estn indizados los mensajes escritos por

mi
*mensaPend lista de mensajes pendientes: arraylist que almacena los indices de los mensajes
pendientes.
Posee mtodos para obtener y actualizar los datos.
Para entender las dos ltimas estructuras hay que explicar que todos los mensajes se almacenan en
una estructura global donde se asocia un entero a un mensaje. Cada vez que algn usuario escribe
un mensaje se almacenan en esta estructura, ordenados segn precedencia a travs de este ndice.
As en Archivador en vez de almacenar de nuevo los mensajes almacenamos el indice del mensaje
en la estructura global. As para recuperar el mensaje basta buscar el indice en la estructura global
de mensajes.
La clase Archivador la utilizan Basededatos, Servidor y los usuarios; Basededatos para recibir los
datos que envian los usuarios, Servidor para enviar los datos de un usuario cuando alguno lo solicita
y los usuarios para poder almacenar y ver sus datos.
Codebase
Clase que establece la propiedad java.rmi.server.codebase. Recibe la interfaz de la clase donde con
su ubicacin poder buscar las clases para cargar y sean accesibles para enviar de forma remota
La clase es utilizada Basededatos y Servidor que son las clases que publican en el registry sus
servicios para que sean accesibles por ejemplo para Usuario, los servicios de Servidor y para
Servidor los servicios de Basededatos.
Mensaje
Implementa Serializable.
Encapsula los mensajes de la Basededatos hacia su receptor.
Tiene dos campos resultado y texto.
El resultado de una operacin, true o false y un mensaje asociado.
Esta clase se utiliza para enviar respuestas de la Basededatos al Servidor y del Servidor al Usuario.
Posee mtodos para obtener y actualizar un mensaje.
Menus
Es una clase auxiliar que escribe por pantalla los mens de cada actor, usuario, servidor o
basededatos.
Cada actor posee su propio menu que se despliega al llamar a sus mtodos. Adems posee un
mtodo para leer por teclado la opcin del men que se elige en cada caso y devolver el resultado al
actor para que ejecute la accin elegida.
Todos los actores utilizan esta clase.
Seguidores
Implementa Serializable para poder ser almacenada de forma permanente en un archivo.
Clase que almacena en un arraylist una lista de usuarios que representan los seguidores de un
usuario dado.
Implementa mtodos para agregar, borrar y consultar estos seguidores o la lista completa de
seguidores.
Basededatos la utiliza para almacenar los seguidores de un usuario.

Seguridad
Clase que establece la propiedad de poltica de seguridad utilizando el archivo /seguridad.policy y
crea de forma temporal una copia de este archivo para que sea accesible a la clase.
Busca el archivo, crea una copia y la incluye en un directorio accesible por el classpath en
C:Users\<nombre usuario>\AppData\Local\Temp\<nombre que le hemos dado>.policy
La seguridad que he establecido en esta caso, es all permission, para permitir todas las conexiones,
ya que no es necesaria ms seguridad en este caso para los fines de la prctica.
Esta clase la utilizan los tres actores, para definir su poltica de conexiones usuarios, servidor y
basededatos.
Descripcin clases obligatorias
Del usuario

Un Usuario utiliza las clases definidas por mi :


- Seguridad
- Mens
- Mensaje
- Archivador
Para poder utilizar los objetos remotos que le brinda el Servidor utiliza:
- ServicioGestorInterface
- ServicioAutenticacionInterface
Para enviar un callback utiliza
- CallbackUsuarioInterface
- CallbackUsuarioImpl

Para enviar un mensaje y su propietario:


- Trino
A su vez
ServicioGestorInterface utiliza:
- la clase mensaje para enviar mensajes de la Basededatos al Usuario
- la interfaz CallbackUsuarioInterface para enviar el objeto remoto del callback hacia la BD.
ServicioAutenticacionInterface utiliza:
- Archivador para enviar los datos encapsulados al usuario
- Mensaje para enviar mensajes de respuesta de la BD
En el diagrama se ve como ServicioAutenticacionInterface esta implementado por
ServicioAutenticacionImpl.
Las interfaces ServicioAutenticacionInterface y ServicioGestorInterface son compartidas con el
Servidor.
Mtodos
De Usuario:
***Nota no he colocado los argumentos en los mtodos aqui por una cuestion de claridad. Estan al
final de la memoria.
entrar() : realiza el login en el sistema y utiliza login() de ServicioAutenticacionImpl
pide los mensajes pendientes con misMensaPend() de ServicioGestorImpl
y envia el callback a utilizando registroCallbck()

registrar(): registra un nuevo usuario


utiliza registro() de ServicioAutenticacionImpl

salir(): establece la variable de corte a "false" para salir del segundo men de usuario
exit(): antes de terminar el usuario pone a null todas sus variables y ejecuta recolector de basura y
terminar el hilo.
usuariosSistema(): devuelve una lista con los usuarios registrados del sistema
utiliza usuarios de ServicioAutenticacionImpl

informacion(): pide la informacion del usuario y la escribe por pantalla


utiliza obtenerDatos() de ServicioAutenticacionImpl

logOff(): cambia el estado del usuario en la BD y si operacion se realiza sale del sistema de forma
segura. Utiliza deslogear().

enviarTrino(): crea un nuevo trino y lo envia


utiliza enviarTrino()

seguirUsuario(): permite seguir a un usuario dado. Agrega mi nick a la lista de seguidores del
usuario que se especifica. utiliza addSeguidor()

dejarDeSeguir: permite dejar de seguir a un usuario dado, nos borra de sus seguidores.
utiliza borrarSeguidor()

De CallbackUsuarioInterface
CallbackUsuarioInterface declara en su interfaz un solo mtodo callBackNotificacion()
que CallbackUsuarioImpl implementa. Este mtodo recibe una cadena, un mensaje y la imprime en
pantalla, se nos notifica de un mensaje enviado por un usuario al que seguimos.
De actor Servidor

ServicioAutenticacionImpl mtodos remotos


Esta clase hace uso de las clases antes descritas Archivador y Mensaje e implemeta la interfaz
ServicioAutenticacionInterface.
Los usuarios se comunican con los mtodos remotos de ServicioAutenticacionImpl y estos a su vez
con los servicios remotos de Basededatos para poder realizar la operativa.
Para ello busca en el registro, el objeto remoto :
URL_Basededatos = "rmi://localhost:"+numeroDePuertoBD+"/ServicioDatos/basededatos" .

Los mtodos ya los hemos nombrado antes cuando describimos a los mtodos de Usuario:
login(): envia los datos a la BD a travs del mtodo loginSistema() y este devuelve un mensaje con
el resultado de la operacin al usuario

registro():enva los datos para registro a la BD a travs del mtodo registrarBD() y este devuelve
un mensaje con el resultado de la operacin al usuario
usuarios():devuelve una lista de los usuarios del sistema que enva la BD al Servidor. Utiliza
listarUsuarios().
estado(): obtiene el estado de una usuario dado a travs de getEstado().
deslogear(): a travs del mtodo salirSistema() envia una peticin para registrar en la BD la salida
del sistema y este devuelve un mensaje con el resultado de la operacin al usuario.
obtenerDatos(): obtiene los datos de la BD con getDatos() y este devuelve un mensaje con el
resultado de la operacin al usuario que ser una instancia de Archivador.

De ServicioGestorImpl mtodos remotos


De forma similar a los mtodos de SevicioAutenticacionImpl pero su funcin es diferente.
Si SevicioAutenticacionImpl se encarga de los datos de los usuarios, SevicioGestorImpl se encarga
de todo lo relacionado con los mensajes de los usuarios.
Esta clase utiliza las clases de apoyo Trino, Mensajes. Utiliza los metodos remotos de la BD y enva
un callback de lo la clase CallbackUsuarioImpl.
Los usuarios se comunican con los mtodos remotos de ServicioGestorImpl y estos a su vez con
los servicios remotos de Basededatos para poder realizar la operativa.
Para ello busca en el registro, el objeto remoto :
URL_Basededatos = "rmi://localhost:"+numeroDePuertoBD+"/ServicioDatos/basededatos" .

Los mtodos ya los hemos nombrado antes cuando describimos a los mtodos de Usuario:
enviarTrino(): envia un trino a la BD, utiliza anadirTrino().
addSeguidor(): aade un seguidor a un usuario en la BD y recibe un mensaje de la operacion
utiliza anadirSeguidor().
borrarSeguidor(): borra un seguidor, usa cutSeguidor() y recibe un mensaje de la operacion.
misMensajesPend(): busca los mensajes pendientes de un usuario y le devuelve la lista con ellos
usa getPendientes().
borrarPend(): una vez que el Servidor enva los mensajes al usuario y los lee, el usuario borra estos

mensajes utilizando este mtodo que a su vez utiliza clearPend() para borrarlos en la
BD.
registroCallback(): usa addCallback() para agregar un objeto remoto de notificacin en la BD
procedente de un usuario.

Servidor
Clase principal del actor Servidor, posee el main del mismo.
Utiliza las clases de apoyo Menus, Seguridad, Codebase.
Ademas de algunos mtodos de la clase ServicioDatosImpl para realizar alguna de sus funciones
como devolver la lista de usuarios logeados.
Publica sus dos servicios en el registry para que sus mtodos sean accesibles de forma remota.
Sus mtodos no son remotos, son locales al Servidor:
listarUsuariosLog: lista los usuarios logeados en ese momento. Utiliza el mtodo listaLogeados() de
la BD
informacin: escribe por pantalla informacin, del nombre de los objetos remotos que ofrece en
formato URL.

El actor Basededatos
La clase ServicioDatosImpl
Aporta los mtodos remotos a los servicios ServicioAutenticacionImpl y ServicioGestorImpl
adems de a la clase Servidor y a la clase Basededatos.
Utiliza las clases de apoyo Archivador, Seguidores, Mensaje, Trino y CallbackUsuarioImpl para
manipular los callbacks.
Adems contiene las estructuras de datos para almacenar toda la informacin del sistema y los
mtodos para manejar esta informacin de forma remota.
Sus mtodos remotos ya los hemos nombrado antes ahora los describimos.

Mtodos remotos
Los divido en los que prestan servicio al ServicioAutenticacionImpl del actor Servidor y a
ServicioGestorImpl del mismo actor, como a la clase Servidor y a la clase Basededatos.
Al ServicioAutenticacionImpl:
registrarBD(): este mtodo registra un nuevo usuario a partir de su nick.
Verifica si el nick est disponible para registro, y si lo est almacena el nick y le
asocia una estructura Archivador con sus datos y su estado a desconectado para que
ya pueda ser seguido por usuarios. Devuelve una respuesta del resultado de la
operacin
loginSistema(): comprueba si los datos pasados son correctos y devuelve una respuesta del
resultado de la operacin.
listarUsuarios(): busca en la estructura de datos datosUsuario todas las claves, todos los usuarios
registrados y las transforma a String y las devuelve como una lista.
salirSistema(): realiza una serie de comprobaciones con el nombre del usuario y si todo es correcto
cambia su estado a desconectado. Devuelve una respuesta del resultado de la

operacion
getEstado(): devuelve el estado del usuario:
getDatos(): devuelve una estructura Archivador con los datos del usuario.
Al ServicioGestorImpl
anadirTrino(): agrega el mensaje a la lista de global de mensajes y al usuario que lo escribio le
agrega un raferencia en Archivador al mensaje. Si el dueo del mensaje tiene
seguidores a cada uno le hace llegar, utilizando el callback almacenado en la
estructura para ello, el mensaje siempre que este en estado conectado, sino
almacena en el Archivador de cada usuario una referencia al mensaje de la lista
global de mensajes, para que cuando haga login se les envien.
anadirSeguidor(): aade un seguidor en una lista de seguidores asociada a cada usuario
cutSeguidor(): borra de esta estructura al seguidor del usuario
getPendientes(): devuelve los mensajes pendientes a un usuario durante el proceso de login del
mismo.
clearPend(): Cuando el usuario ha leido sus mensajes pendientes este enva un mtodo, que a travs
del servidor borra la lista de mensajes pendientes.
addCallback(): aade un callback que enva un usuario al logearse y lo almacena en una estructura
de datos asociada al nombre de quien lo enva.
Este mtodo realiza otra modificacin en el usuario. Cuando un usuario realiza un
login su estado es desconectado. Cuando en la BD se almacena el callback el
usuario pasa a estado conectado, ya que si lo hiciese en el momento del login si
transcurriese un tiempo entre que el estado es conectado y el callback no ha llegado
aun, y el usuario del callback estuviera siguiendo a algn otro usuario y este enva
un mensaje, no podra conectarse y tendramos una excepcin. Cuando el usuario
se logea el mtodo que lo hace invoca tres mtodos uno para logearse otro para
enviar el callback. y otro para recibir mensajes nuevos. As cuando el primero se
ejecuta con xito y el segundo todava no ha llegado hasta la BD, a travs del
servidor, este usuario puede seguir almacenando mensajes pendientes y no perder
ninguno. Luego cuando el callback llega cambia de estado a conectado y luego
recibe la lista de mensajes pendientes.
Locales a la clase
convertToString(): convierte a formato String un mensaje para enviarlo habiendo transformado el
timestamp a una fecha.
convertirMillis(): transforma el timestamp a una fecha del calendario
A la clase Basededatos
cargarBD(): se encarga de cargar desde un archivo .txt todos los datos de la BD, previamente
almacenados.
respaldarBD(): antes de cerrar la BD se guardan todas las ED en un archivo .txt
getListaMensa(): devuelve la lista de todos los mensajes.
A la clase Servidor
listaLogeados(): devuelve la lista de usuarios logeados en ese momento
A ServicioAutenticacionImpl y a Servidor
listarUsuarios(): devuelve la lista, el nick, de todos los usuarios registrados hasta el momento.
Clase Basededatos

Esta clase implemta el main de la BD y publica el servicio de la misma en el registry.


Utiliza las clases de apoyo Seguridad, Codebase, Menus, y adems utiliza algunos mtodos de la
clase ServicioDatosImpl.
realiza varias funciones como ver todos los mensajes del sistema y todos los usuarios del mismo,
ademas del nombre del objeto remoto en formato URL
rmi://localhost:"+numeroDePuertoBD+"/ServicioDatos/basededatos

Otra funcin que realiza es que cuando se cierra, pide la lista de usuarios logeados en ese momento
y pone su estado a desconectado, para evitar inconsistencias. Si la BD se cierra y hay usuarios
logeados, entonces estos no pueden cambiar su estado, y la sesin quedara abierta y no nos
podramos logear nuevamente.
Los usuarios en todo momento chequean su estado para saber si hay algn problema con la base de
datos. Si la BD esta caida generar un excepcion en el usuario y se cerrar.
Estructuras de datos para almacenar los datos.
Map<String, Archivador> datosUsuario = new HashMap<String, Archivador>();
Map<Integer , Trino> listaMensajes = new HashMap<Integer, Trino>();
Map<String, Seguidores> listaSeguidores = new HashMap<String, Seguidores>();
Map<String, CallbackUsuarioInterface> listaCallBack = new HashMap<String,
CallbackUsuarioInterface>();

Son cuatro estructuras

Funcionamiento
Cuando un usuario se registra sus datos se almacenan en datosUsuario en un Archivador. De ahi se
pueden recuparar.
Cuando el usuario hace login se enva el callback y se almacena en listaCallBack y se recuperan
desde listaMensajes los mensajes pendientes cuya referencia estaba en Archivador
Si un usuario enva un mensaje, el mensaje se almacena en la listaMensajes, la posicin que tiene el
mensaje en la ED que lo contiene se almacena en Archivador, para tener una referencia del mensaje
en la lista. Se busca en la lista listaSeguidores por su nick y se buscan sus seguidores y luego para
cada uno de ellos si su estado es desconectado, lo buscamos en su Archivador, guardamos los
mensajes en pendientes, una referencia al mensaje en listaMensajes. Si el estado es conectado, se
busca con su nick en la listaCallBack para obtener el objeto remoto y ejecutar su mtodo para
devolver al usuario que sigue al que ha escrito el mensaje, el mensaje.
Si queremos seguir a un usuario con el nick del usuario al que vamos a seguir lo buscamos en
listaSeguidores y agregamos nuestro nick a su lista de seguidores.
Si queremos dejar de seguir a un usuario, con su nick buscamos y borramos el nuestra de la lista.
Si queremos conocer todos los usuarios del sistema buscamos en datosUsuario los nombre de los
usuarios registrados.
Capturas de pantalla

inicio de la base de datos

no existen usuarios registrados

inicio del servidor

no existen usuarios logeados

inicio y registro de un usuario

ya aparece el usuario registrados

login de jasd

registro y login de qwert

seguir a qwert y recepcion del mensaje de qwert

qwert envia un mensaje

jasd se logea y recibe el mensaje pendiente, qwert vuelve a escribir y jasd vuelve a recibir el

mensaje de forma automatica.

lista de usuarios logeados y de mensajes del sistema.

jasd se ha deslogeado y se ven desde qwert todos los usuarios del sistema

jasd y wert se han deslogeado el servidor y la basededatos de han cerrado, se han vuelto a poner en

funcionamiento y se ven los usuarios regitrados los mensajes y que no hay usuarios logeados.
Conclusiones:
Para los que no estamos acostumbrados al mundo java y mas a RMI es un desafo comprender los
conceptos para luego aplicarlos. Con el tiempo los conceptos se asientan y las cosas parecen ms
fciles. En internet hay mucha informacin al respeto de java, ejemplos de RMI y de callbacks.
Pero sin duda el video de Fermn y las vdeo tutorias me han sido muy tiles pero sobre todo
experimentar un poco con las herramientas. Nunca haba usado eclipse y en esta ocasin lo he
utilizado y el resultado ha sido muy bueno. Quizas faltan explicar un poco mejor lo de los classpath
que dan mucho dolor de cabeza.
Pero en definitiva ha sido un proceso entretenido.
Mtodos de las clases
Archivador
void

addIndiceTrino(int indice)

void

addPendiente(int indice)

void

borraListaPend()

String

getEstado()

Integer

getIndicePend(int indice)

Integer

getIndiceTrino(int indice)

int

getLargoLista()

int

getLargoListaPend()

String

getMail()

String

getNombre()

String

getPassword()

void

setEstado(String estado)

void

setMail(String mail)

void

setNombre(String nombre)

void

setPassword(String password)

Basededatos
static void

informacion()

static void

listarTrinos()

static void

listarUsuarios()

static void

main(String[] args)

CallbackUsuarioImpl
void callBackNotificacion(String mensaje)
Codebase
static void

setCodeBase(Class<?> c)

Menus
String

leerTeclado()

void

menuBD()

void

menuCliente1()

void

menuCliente2()

void

menuServidor()

Mensaje
String

getRespuesta()

String

getTexto()

void

setRespuesta(String respuesta)

void

setTexto(String texto)

Seguidores
void

addSeguidor(String usuario)

void

borrarSeguidor(String seguidor)

ArrayList<

getListaSeguidores()

String>

getSeguidor(int indice)

String

Seguridad
tatic String
static void

getLocationOfPolicyFile()
main(String[] args)

Servidor
static void

informacion()

static void

listarUsuariosLog()

static void

main(String[] args)

ServicioAutenticacionImpl
Mensaje deslogear(String nombre)
String
Mensaje
Archivador
Mensaje

ArrayList<
String>

estado(String usuario)
login(String usuario, String contrasena)
obtenerDatos(String usuario)
registro(String nick, String nombre, String mail,
String password)
usuarios

ServicioDatosImpl
void addCallback(String usuario,
CallbackUsuarioInterface objCallback)
Mensaje

anadirSeguidor(String seguidor, String aSeguir)

void

anadirTrino(Trino trino)

void

cargarBD()

void

clearPend(String usuario)

String

convertirMillis(long milliseconds)

String

convertToString(Trino trino)

Mensaje
Archivador
String

cutSeguidor(String seguidor, String aSeguir)


getDatos(String usuario)
getEstado(String usuario)

ArrayList<
String>

getListaMensa()

ArrayList<
String>

getMisSeguidores(String usuario)

ArrayList<
String>

getPendientes(String usuario)

ArrayList<
String>

listaLogeados()

ArrayList<
String>

listarUsuarios()

Mensaje

loginSistema(String usuario, String contrasena)

Mensaje

registrarBD(String nickname, String nombre, String mail,


String password)

void
Mensaje
void

respaldarBD()
salirSistema(String nombre)
setEstado(String usuario)

ServicioGestorImpl
Mensaje addSeguidor(String sigue, String sigueA)
void
Mensaje
void

borrarPend(String usuario)
borrarSeguidor(String sigue, String sigueA)
enviarTrino(Trino trino)

ArrayList<
String>
void

misMensajesPend(String usuario)
registroCallback(String usuario,
CallbackUsuarioInterface objCallback)

Trino
String
long

ObtenerNickPropietario()
ObtenerTimestamp()

String

ObtenerTrino()

String

toString()

Usuario
static void

dejardeSeguir()

static void

entrar()

static void

enviarTrino()

static void

exit()

static void

informacion()

static void

logOff()

static void

main(String[] args)

static void

registrar()

static void

salir()

static void

seguirUsuario()

static void

usuariosSistema()