Bueno, vamos a ponernos ya manos a la obra con el tutorial java rmi. En primer lugar vamos a desarrollar el Servidor, que publica tres servicios y se encarga de la autenticación, el almacenamiento de los clientes y los repositorios y la gestión de las relacione entre estos.
Tened en cuenta que esta serie de posts van a ser más bien prácticos. Me gustaría hacer uno un poco más teórico sobre JavaRMI más adelante, pero ya veremos…
Para esta práctica vamos a suponer que los tres agentes se ejecutan en local y que levantamos el registro rmi en el puerto 1492. En posteriores entradas publicaré distintas configuraciones.
Para el servidor vamos a hacer uso de 4 clases y 3 interfaces.
Clases:
- Servidor. Contiene el main del servidor que levanta los servicios y muestra el menú.
- ServicioAutenticacionImpl. Contiene la implementación de la interfaz ServicioAutenticacionInterface.
- ServicioDatosImpl. Contiene la implementación de la interfaz ServicioDatosImpl.
- ServicioGestorImpl. Contiene la implementación de la interfaz ServicioGestorInterface.
Interfaces:
- ServicioAutenticacionInterface. Contiene la interfaz con los métodos necesarios para la autenticación de clientes y repositorios.
- ServicioDatosInterafce. Contiene la interfaz con los métodos necesarios para el almacenamiento de datos. Normalmente sería una base de datos, pero para este ejemplo usaremos las clases Map y List de java.
- ServicioGestorInterface. Contiene la interfaz con los métodos necesarios para la gestión de los repositorios y los clientes.
Pues nada, lo primero las interfaces.
ServicioDatosInterface
import java.rmi.Remote; import java.rmi.RemoteException; import java.util.Collection; import java.util.HashMap; public interface ServicioDatosInterface extends Remote{ public boolean ingresaCliente(String nombre, int id) throws RemoteException; public boolean ingresaRepositorio(String nombre, int id) throws RemoteException; public Collection<String> listaClientes() throws RemoteException; public Collection<String> listaRepositorios() throws RemoteException; public void listarRepositoriosClientes() throws RemoteException; public int buscaRepositorio(int cliente) throws RemoteException; }
En primer lugar analizaremos la interfaz Datos, porque esta interfaz es usada por los otros servicios para llevar a cabo sus funciones.
Todas las interfaces van a extender de Remote que es una interfaz que sirve para identificar interfaces (valga la redundancia) cuyos métodos pueden ser invocados desde una máquina virtual no local.
Así mismo, todos los métodos pertenecientes a las interfaces deberán lanzar la excepción RemoteException. Esto es muy importante, ya que los métodos que de las interfaces que no lancen esta excepción no serán reconocidos como remotos y no podrán ser invocados.
Por lo demás, los métodos son:
- ingresaCliente. Para añadir un cliente recibiendo como parámetro el nombre y la id.
- ingresaRepositorio. Para añadir un repositorio recibiendo como parámetro el nombre y la id.
- listaClientes. Que nos devuelve una lista con los nombres de los clientes.
- listaRepositorios. Devuelve una lista con los nombres de los repositorios.
- buscaRepositorio. Devuelve el id de un repositorio recibiendo como parámetro la id de un cliente.
ServicioAutenticacionInteface
import java.rmi.Remote; import java.rmi.RemoteException; public interface ServicioAutenticacionInterface extends Remote { public int autenticarCliente(String nombre) throws RemoteException; public int autenticarRepositorio(String nombre) throws RemoteException; }
La interfaz Autenticación, como su nombre indica va a llevar a cabo la autenticación tanto de Clientes como de Repositorios y para ello va a publicar dos métodos:
- autenticarCliente. Que autentica a los clientes recibiendo como parámetro el nombre del Cliente y devolviendo una id que lo identificara unívocamente.
- autenticarRepositorio. Que hace lo mismo que autenticarCliente para los repositorios.
A la hora de implementar estas funciones, yo lo he hecho de tal manera que no haya dos clientes con el mismo nombre en el servicio, pero eso ya es cosa de cada uno.
ServicioGestorInterface
import java.net.MalformedURLException; import java.rmi.NotBoundException; import java.rmi.Remote; import java.rmi.RemoteException; public interface ServicioGestorInterface extends Remote{ public String obtenerServicioClienteOperador(int id) throws RemoteException, NotBoundException, MalformedURLException; public String obtenerServicioServidorOperador(int id) throws RemoteException, NotBoundException, MalformedURLException; }
Por último la interface Gestor, se encarga de «conectar» a los repositorios con los clientes. Asigna a cada cliente un repositorio y más tarde facilita tanto a clientes como repositorios la localización de los servicios desplegados por éstos para que intercambien archivos. Puede resultar un poco lioso sin ver el código pero al implementarlo se verá perfectamente claro. Esta interfaz publica dos Métodos:
- obtenerServicioClienteOperador. Este método proporciona a los clientes la dirección del servicio Cliente-Operador de su repositorio.
- obtenerServicioServidorOperador. Este método proporciona a los clientes la dirección del servicio Servidor-Operador de su repositorio.
Y bueno, éstas son las interfaces del Servidor. Al comenzar la entrada tenía la idea de hacer sólo una entrada para el Servidor, pero la verdad es que no me gustan las entradas largas así que lo voy a dividir en varias partes y así también puedo explicar más cosas. Así que aquí lo dejamos por ahora. En la siguiente entrada veremos las clases de implementación de las interfaces.
Un saludo.
Deja un comentario