El microservicio como base.#

El sistema estará dividido en diferentes microservicios, cada uno encargado de realizar una de las diferentes tareas que tiene que realizar el sistema en su conjunto.

La interfaz Slice#

Cómo ya sabéis, el alma de la comunicación entre clientes y servicios en un entorno RMI es la interfaz. En ZeroC ICE esa interfaz se define en el IDL específico del middleware, Slice.

El código de la interfaz podéis encontrarlo aquí. Se recomienda leer la descripción de los servicios con el fichero Slice, para identificar las interfaz, métodos y argumentos aquí especificados.

Servicio de autenticación.#

La autenticación en el servicio se gestiona a través de este servicio. El usuario debe enviar un usuario y contraseña periódicamente, obteniendo un token de autenticación que tendrá una validez limitada en el tiempo (2 minutos). También se encarga de realizar la comprobación de si un token es válido o no para el resto de servicios del sistema.

Para arrancar este servicio debe proporcionarse un token de administración, que deberá ser almacenado en memoria para poder realizar la comprobación de su validez en aquellas operaciones que requieren de dicho token. Éste token se pasará a través del fichero de configuración.

El servicio debe almacenar en una base de datos persistente entre reinicios (no necesariamente debe ser SQL) las credenciales de los usuarios. Los tokens, por su naturaleza temporal, no deben aparecer en ese almacenamiento persistente.

Adicionalmente proporciona al administrador la funcionalidad de añadir y eliminar usuarios.

Dicho servicio implementa la interfaz Authenticator:

  • refreshAuthorization(): crea un nuevo token de autorización de usuario si las credenciales son válidas.

  • isAuthorized(): indica si un token dado es válido o no.

  • whois(): permite descubrir el nombre del usuario a partir de un token válido.

  • isAdmin(): devuelve un valor booleano para comprobar si el token proporcionado corresponde o no con el administrativo.

  • addUser(): función administrativa que permite añadir unas nuevas credenciales en el almacén de datos si el token administrativo es correcto.

  • removeUser(): función administrativa que permite eliminar unas credenciales del almacén de datos si el token administrativo es correcto.

Servicio de ficheros#

En lugar de implementar un servicio de streaming como se la plataforma real, en esta práctica se va a implementar un servicio de descargas.

El servicio de ficheros se encarga de enviar al usuario el fichero para que pueda visualizarlo. El servicio debe leer de un directorio en el disco duro, que será pasado al servicio a través de su configuración, los ficheros que serán compartidos.

El servicio deberá anunciar a los posibles catálogos de forma periódica una lista de los archivos alojados en el directorio. Para ello usará la interfaz FileAvailabilityAnnounce como se verá en el apartado siguiente.

  • newMedia(): será emitido por el servicio cuando se encuentre un nuevo fichero o sea subido uno nuevo por el administrador.

  • removedMedia(): se emitirá cuando un fichero sea eliminado del servicio por el administrador.

El identificador de un medio, utilizado tanto por el servicio de ficheros como por el catálogo, se calculará en función del contenido del fichero (función hash). Para ello, puede utilizarse la suma SHA256 del fichero.

El servicio implementa la interfaz FileService:

  • openFile(): dado el identificador del medio devolverá un proxy al manejador del archivo (FileHandler), que permitirá descargarlo.

  • uploadFile(): dado el token de administrador y un proxy para la subida del archivo, lo guardará en el directorio y devolverá su identificador.

  • removeFile(): dado un identificador y el token de administrador, borrará el archivo del directorio.

Cuando un usuario solicite abrir un fichero, el servicio creará un sirviente para manejar su posible descarga. Ésta se manejará a través de la interfaz FileHandler, que para todas las operaciones solicitará el token del usuario, que debe ser siempre el mismo que solicitó su apertura

Las operaciones disponibles en la interfaz FileHandler son:

  • receive(): recibe el número indicado de bytes del archivo.

  • close(): indica al servidor que el proxy para este fichero ya no va a ser usado y puede ser eliminado.

Descarga de ficheros#

Cuando un usuario abre un fichero a través de openFile en el servicio, el manejador de fichero debe ser consciente en todo momento de a qué usuario pertenece el token y, si éste expírase en algún momento, devolver la excepción adecuada.

Si el cliente recibiera dicha excepción durante la descarga, deberá renovar su token y utilizar el nuevo para poder continuar la descarga.

Subida de ficheros#

Si el usuario es, además, administrador de la plataforma, puede utilizar el método uploadFile() del servicio para realizar una descarga.

Para ello el cliente deberá proporcionar un proxy a un sirviente de la interfaz FileUploader, a través del cuál el servicio irá solicitando la subida del fichero al cliente.