SISTEMAS DISTRIBUIDOS DE CÁLCULO INTENSIVO

Anuncio
PROYECTO FINAL DE CARRERA
SISTEMAS DISTRIBUIDOS DE
CÁLCULO INTENSIVO
Ponente: Sergio Gómez
Alumno: Carmelo Aguilar García
E.T.I.S.
Septiembre 2005
1
1.- INTRODUCCIÓN Y OBJETIVOS
1.1.- INTRODUCCIÓN
Actualmente el uso de programas informáticos para la investigación y resolución de
problemas es algo normal, de echo muchas investigaciones no serían posibles sin un programa
informático capaz de computar cualquier problema infinitamente más rápido que un ser
humano normal...
Aún así algunas investigaciones, por su complejidad requieren una potencia de cálculo
mucho mayor que la que puede ofrecer el mejor superordenador que podamos imaginar... Es
por eso que se ideó la “computación distribuida”, capaz de resolver problemas de computación
masiva utilizando un gran número de ordenadores organizados en racimos incrustados en una
infraestructura de telecomunicaciones distribuida.. como por ejemplo podría ser Internet.
1.2.- OBJETIVOS
El objetivo de este proyecto es crear un programa Servidor-Cliente capaz de gestionar y
llevar a cabo un proyecto-investigación de estas características. Es decir un Servidor que sea
capaz de administrar toda la información que genere nuestro proyecto, tales como clientes
registrados, trabajos disponibles, trabajos asignados, trabajos completados, así como ser capaz
de corregir posibles fallos que impidan el correcto funcionamiento de dicho Servidor. Y un
Cliente capaz de hacer peticiones al Servidor y además aprovechar la capacidad de
procesamiento del ordenador remoto, conectado a cualquier punto de la red global, en que esté
instalado para computar-procesar una aplicación con un coste de CPU demasiado elevado
como para que pueda realizarse en un solo ordenador.
Así pues crearemos nuestro propio proyecto de investigación que utilice la computación
distribuida como herramienta de trabajo. Para que el Cliente pueda interactuar con el Servidor
y realizar así su trabajo utilizaremos la tecnología RMI (Remote Method Invocation) que
permite realizar llamadas a funciones de forma remota, es invocar funciones que se encuentran
en otro ordenador.
Así pues nuestro programa Servidor-Cliente tendrá las siguientes tareas.:
El Servidor será el administrador de toda la información necesaria para el correcto
funcionamiento de nuestra investigación. Es decir será el encargado de:
Enviar los archivos disponibles a los clientes, asignar los archivos a los clientes, recibir
los archivos computados de los clientes, guardar los archivos ya completados, controlar que un
archivo no tarde demasiado en ser procesado, mantener una política de orden de envío de
trabajos a partir de su prioridad, añadir nuevos archivos para analizar, dar de alta a nuevos
clientes, llevar un registro “log” de los incidentes o sucesos que se puedan registrar a lo largo
del día, borrar archivos de análisis o analizados que estén dañados, recuperar archivos
perdidos a partir de copias de seguridad, avisar al administrador de que se ha producido un
error critico, y sobretodo mantener toda esta información accesible en todo momento para que
el administrador pueda hacer uso de ella, para ello utilizaremos una Base de Datos donde
almacenaremos toda esta información, y una Interface gráfica lo suficientemente elocuente y
clara para poder manejar todos estos datos.
El trabajo del Cliente consistirá en:
Descargar el fichero que le envíe el Servidor, analizar los datos (es decir aplicar sobre los
datos nuestro programa de cálculo intensivo), y una vez acabado el análisis, enviar los datos
obtenidos al programa Servidor para su almacenamiento. Todo ello debe poder realizarse sin
que el usuario Cliente tenga que prestar ninguna a la aplicación, a no ser que el mismo usuario
lo desee por cuestión de simple curiosidad, o para comprobar que esta realizando su
ordenador.
Una vez que nuestro Servidor-Cliente sea consistente y robusto, procederemos a crear una
aplicación de calculo intensivo que se pueda ejecutar aprovechando la Interface que crea el
cliente. Este programa debería ser independiente del cliente, es decir, que pudiéramos ejecutar
cualquier programa desde el cliente sin tener que variar su código.
2
2.- ANTECEDENTES
2.1.- COMPUTACIÓN DISTRIBUIDA
La computación distribuida o computación en grilla es un nuevo modelo para resolver
problemas de computación masiva utilizando un gran número de ordenadores organizados en
racimos incrustados en una infraestructura de telecomunicaciones distribuida.
La informática en grilla consiste en compartir recursos heterogéneos (basadas en distintas
plataformas, arquitecturas de equipos y programas, lenguajes de programación, etc...), situados
en distintos lugares y pertenecientes a diferentes dominios de administración sobre una red
que utiliza estándares abiertos. Dicho brevemente, consiste en virtualizar los recursos
informáticos. Es decir crear un gigantesco ‘ordenador virtual’ capaz de una potencia de
computación inimaginable.
La computación distribuida o computación en grilla ha sido diseñada para resolver
problemas demasiado grandes por cualquier simple superordenador, mientras mantiene la
flexibilidad de trabajar en múltiples problemas más pequeños. Por tanto, la computación en
grilla es naturalmente un entorno multi-usuario; debido a esta razón, las técnicas de
autorización segura son esenciales para permitir que los recursos informáticos sean
controlados por usuarios remotos (distantes).
Este modelo de computación permite disponer de redes de ordenadores dedicados al
análisis de datos que requieran una gran potencia de cómputo.
Un ejemplo lo podemos encontrar en el proyecto BOINC (Berkeley Open Infrastructure
for Network Computing), una plataforma de propósito general para proyectos de computación
distribuida, que permite compartir el tiempo de sus contribuyentes con otros proyectos.
Ciclos de CPU libres, ese es el concepto, mientras lees tu correo tu CPU no trabaja, pero
puede contribuir al análisis de datos científicos.
Desde cualquier ordenador personal se puede contribuir a cualquier proyecto de
investigación científica basado en la tecnología BOINC. Únicamente es necesario bajarse el
software BOINC y elegir uno de los proyectos disponibles:
Algunos ejemplos de estos proyectos son:
- Climateprediction.net → Estudia el cambio climático.
- Einstein@home → Búsqueda de signos gravitacionales provenientes de pulsars.
- SETI@home → Búsqueda de señales de radio que evidencien vida extraterrestre.
- ...
3
2.2.- SETI@home
Un ejemplo de estos proyectos es como ya hemos dicho SETI@home basado en el
proyecto radio SETI:
Radio SETI, usa radiotelescopios para escuchar señales de radio en banda estrecha
provenientes del espacio. Éstas señales se sabe que no ocurren naturalmente, por lo que su
detección sería la evidencia de una tecnología extraterrestre.
Las señales de los radiotelescopios consisten fundamentalmente en ruidos (provenientes
de fuentes celestiales y de la electrónica del receptor) y señales producidas por el hombre
como las de estaciones de televisión, radares y satélites. Los proyectos modernos de radio
SETI analizan éstos datos digitalmente aplicando diferentes operaciones tales como
transformadas de fourier, gausianas, búsqueda de pulsos, deriva de Doppler... Una mayor
potencia de cálculo permite que la búsqueda cubra un mayor rango de frecuencias con más
sensibilidad. Es por eso que radio SETI, necesita una increíble potencia de cálculo.
El modelo de computación de ciclos redundantes, también conocido como computación
zombi, es el empleado por esta aplicación, consistente en que un servidor o grupo de
servidores distribuyen trabajo de procesamiento a un grupo de computadoras voluntarias a
ceder capacidad de procesamiento no utilizada. Básicamente, cuando dejamos nuestro
ordenador encendido, pero sin utilizarlo, la capacidad de procesamiento se desperdicia por lo
general en algún protector de pantalla, este tipo de procesamiento distribuido utiliza nuestra
computadora cuando nosotros no la necesitamos, aprovechando al máximo la capacidad de
procesamiento.
2.3.- APLICACIÓN SERVIDOR-CLIENTE
La arquitectura servidor-cliente llamado modelo cliente-servidor o servidor-cliente es
una forma de dividir y especializar programas y equipos de computo a fin de que la tarea que
cada uno de ellos realiza se efectúe con la mayor eficiencia, y permita simplificar las
actualizaciones y mantenimiento del sistema.
En esta arquitectura la capacidad de proceso está repartida entre el servidor y los clientes.
En la funcionalidad de un programa distribuido se pueden distinguir 3 capas o niveles:
1. Manejador de Base de Datos (Nivel de almacenamiento),
2. Procesador de aplicaciones o reglas del negocio (Nivel lógico)
3. Interface del usuario (Nivel de presentación)
En una arquitectura monolítica no hay distribución; los tres niveles tienen lugar en el
mismo equipo.
En un comienzo, los mainframes (ordenadores centrales) concentraban la funcionalidad de
almacenamiento (#1) y lógica (#2) y a ellos se conectaban terminales tontas (teclado +
pantalla), posiblemente ubicadas en sitios remotos.
En el modelo cliente-servidor, en cambio, el trabajo se reparte entre dos ordenadores. De
acuerdo con la distribución de la lógica de la aplicación hay dos posibilidades:
1. Cliente delgado: si el cliente solo se hace cargo de la presentación.
2. Cliente pesado: si el cliente asume también la lógica del negocio.
En la actualidad se suele hablar de arquitectura de tres niveles, donde la capa de
almacenamiento y la de aplicación se ubican en (al menos) dos servidores diferentes,
conocidos como servidores de datos y servidores de aplicaciones.
Ventajas de la arquitectura cliente-servidor
• El servidor no necesita tanta potencia de procesamiento, parte del proceso se reparte con
los clientes.
• Se reduce el tráfico de red considerablemente. Idealmente, el cliente se conecta al servidor
cuando es estrictamente necesario, obtiene los datos que necesita y cierra la conexión
dejando la red libre.
4
3.- TECNOLOGÍAS UTILIZADAS:
3.1.- JAVA
Sun Microsystems es quien ha desarrolló el lenguaje Java, en un intento de resolver
simultáneamente todos los problemas que se planteaban a los desarrolladores de software por
la proliferación de arquitecturas incompatibles, tanto entre las diferentes máquinas como entre
los diversos sistemas operativos y sistemas de ventanas que funcionaban sobre una misma
máquina, añadiendo la dificultad de crear aplicaciones distribuidas en una red como Internet.
Características de Java
- Simple
Java ofrece toda la funcionalidad de un lenguaje potente, pero sin las características
menos usadas y más confusas de éstos.
Java elimina muchas de las características de otros lenguajes como C++, para mantener
reducidas las especificaciones del lenguaje y añadir características muy útiles como el
garbage collector (reciclador de memoria dinámica.
- Orientado a objetos
Java trabaja con sus datos como objetos y con interfaces a esos objetos. Soporta las tres
características propias del paradigma de la orientación a objetos: encapsulación, herencia
y polimorfismo.
- Distribuido
Java se ha construido con extensas capacidades de interconexión TCP/IP. Existen librerías
de rutinas para acceder e interactuar con protocolos como http y ftp.
Java en sí no es distribuido, sino que proporciona las librerías y herramientas para que los
programas puedan ser distribuidos.
- Robusto
Java realiza verificaciones en busca de problemas tanto en tiempo de compilación como
en tiempo de ejecución.
Además, para asegurar el funcionamiento de la aplicación, realiza una verificación de los
byte-codes, que son el resultado de la compilación de un programa Java. Es un código de
máquina virtual que es interpretado por el intérprete Java.
- Arquitectura neutral
Para establecer Java como parte integral de la red, el compilador Java compila su código a
un fichero objeto de formato independiente de la arquitectura de la máquina en que se
ejecutará. Cualquier máquina que tenga el sistema de ejecución (run-time) puede ejecutar
ese código objeto, sin importar en modo alguno la máquina en que ha sido generado.
-
Seguro
5
El código Java pasa muchos tests antes de ejecutarse en una máquina. El código se pasa a
través de un verificador de byte-codes que comprueba el formato de los fragmentos de
código y aplica un probador de teoremas para detectar fragmentos de código ilegal -código
que falsea punteros, viola derechos de acceso sobre objetos o intenta cambiar el tipo o
clase de un objeto.
- Portable
Más allá de la portabilidad básica por ser de arquitectura independiente, Java implementa
otros estándares de portabilidad para facilitar el desarrollo. Java construye sus interfaces
de usuario a través de un sistema abstracto de ventanas de forma que las ventanas puedan
ser implantadas en entornos Unix, Pc o Mac.
- Interpretado
El intérprete Java (sistema run-time) puede ejecutar directamente el código objeto. Enlazar
(linkar) un programa, normalmente, consume menos recursos que compilarlo, por lo que
los desarrolladores con Java pasarán más tiempo desarrollando y menos esperando por el
ordenador.
- Multithreaded
Al ser multithreaded (multihilvanado, en mala traducción), Java permite muchas
actividades simultáneas en un programa.
El beneficio de ser multithreaded consiste en un mejor rendimiento interactivo y mejor
comportamiento en tiempo real.
- Dinámico
Java no intenta conectar todos los módulos que comprenden una aplicación hasta el
tiempo de ejecución. Las librería nuevas o actualizadas no paralizarán las aplicaciones
actuales (siempre que mantengan el API anterior).
3.2.- RMI
El sistema de Invocación Remota de Métodos (RMI) de Java permite a un objeto que se
está ejecutando en una Máquina Virtual Java (VM) llamar a métodos de otro objeto que está
en otra VM diferente.
Las aplicaciones RMI normalmente comprenden dos programas separados: un servidor y
un cliente. Una aplicación servidor típica crea un montón de objetos remotos, hace accesibles
unas referencias a dichos objetos remotos, y espera a que los clientes llamen a estos métodos u
objetos remotos. Una aplicación cliente típica obtiene una referencia remota de uno o más
objetos remotos en el servidor y llama a sus métodos. RMI proporciona el mecanismo por el
que se comunican y se pasan información del cliente al servidor y viceversa. Cuando es una
aplicación algunas veces nos referimos a ella como Aplicación de Objetos Distribuidos.
Las aplicaciones de objetos distribuidos necesitan.
Localizar Objetos Remotos
Puede registrar sus objetos remotos con la facilidad de nombrado de RMI rmiregistry.
O puede pasar y devolver referencias de objetos remotos como parte de su operación
normal.
Comunicar con Objetos Remotos
Los detalles de la comunicación son manejados por el RMI, para el programador, la
comunicación remota se parecerá a una llamada estándar a un método Java.
Cargar Bytecodes para objetos que son enviados.
Como RMI permite al llamador pasar objetos Java a objetos remotos, RMI
proporciona el mecanismo necesario para cargar el código del objeto, así como la
transmisión de sus datos.
6
La siguiente ilustración muestra una aplicación RMI distribuida que utiliza el registro para
obtener referencias a objetos remotos. El servidor llama al registro para asociar un nombre con
un objeto remoto. El cliente busca el objeto remoto por su nombre en el registro del servidor y
luego llama a un método. Esta ilustración también muestra que el sistema RMI utiliza una
servidor Web existente para cargar los Bytecodes de la clase Java, desde el servidor al cliente
y desde el cliente al servidor, para los objetos que necesita.
Ventajas de la Carga Dinámica de Código
Una de las principales y únicas características de RMI es la habilidad de descargar los
bytecodes (o simplemente, código) de una clase de un objeto si la clase no está definida en la
máquina virtual del receptor. RMI pasa los objetos por su tipo verdadero, por eso el
comportamiento de dichos objetos no cambia cuando son enviados a otra máquina virtual.
Una aplicación distribuida construida utilizando RMI de Java, al igual que otras
aplicaciones Java, está compuesta por interfaces y clases. Los interfaces definen métodos,
mientras que las clases implementan los métodos definidos en los interfaces. Los objetos que
tienen métodos que pueden llamarse por distintas máquinas virtuales son los objetos remotos.
Un objeto se convierte en remoto implementando un interface remoto.
• Un interface remoto desciende del interface java.rmi.Remote.
• Cada método del interface declara que lanza una java.rmi.RemoteException además
de cualquier excepción específica de la aplicación.
El RMI trata a un objeto remoto de forma diferente a como lo hace con los objetos noremotos cuando el objeto es pasado desde una máquina virtual a otra. En vez de hacer una
copia de la implementación del objeto en la máquina virtual que lo recibe, RMI pasa un stub
para un objeto remoto. El stub actúa como la representación local o proxy del objeto remoto y
básicamente, para el llamador, es la referencia remota. El llamador invoca un método en el
stub local que es responsable de llevar a cabo la llamada al objeto remoto.
Un stub para un objeto remoto implementa el mismo conjunto de interfaces remotos que el
objeto remoto. Esto permite que el stub sea tipado a cualquiera de los interfaces que el objeto
remoto implementa. Sin embargo, esto también significa que sólo aquellos métodos definidos
en un interface remoto están disponibles para ser llamados en la máquina virtual que lo recibe.
7
3.3.- SWING
Para explicar Swing, explicaremos antes que es AWT.
AWT es la biblioteca de clases Java para el desarrollo de Interfaces de Usuario Gráficas.
La versión del AWT es la parte más débil de todo lo que representa Java como lenguaje. El
entorno que ofrece es demasiado simple, no se han tenido en cuenta las ideas de entornos
gráficos novedosos.
Javasoft, en vista de la precariedad de que hace gala el AWT, y para asegurarse que los
elementos que desarrolla para generar interfaces gráficas sean fácilmente transportables entre
plataformas, se ha unido con Netscape, IBM y Lighthouse Design para crear un conjunto de
clases que proporcionen una sensación visual agradable y sean más fáciles de utilizar por el
programador. Esta colección de clases son las Java Foundation Classes (JFC), que están
constituidas por cinco grupos de clases, al menos en este momento: AWT, Java 2D,
Accesibilidad, Arrastrar y Soltar y Swing.
AWT, engloba a todos los componentes del AWT que existían en la versión 1.1.2 del JDK
y en los que se han incorporado en versiones posteriores:
• Java 2D
• Accesibilidad
• Arrastrar y Soltar (Drag and Drop), son clases en las que se soporta Glasgow, que
es la nueva generación de los JavaBeans
• Swing, es la parte más importante y la que más desarrollada se encuentra. Ha sido
creada en conjunción con Netscape y proporciona una serie de componentes muy bien
descritos y especificados de forma que su presentación visual es independiente de la
plataforma en que se ejecute el applet o la aplicación que utilice estas clases. Swing
simplemente extiende el AWT añadiendo un conjunto de componentes, JComponents,
y sus clases de soporte.
La estructura básica del AWT se basa en Componentes y Contenedores. Estos últimos
contienen Componentes posicionados a su respecto y son Componentes a su vez, de forma que
los eventos pueden tratarse tanto en Contenedores como en Componentes, corriendo por
cuenta del programador el encaje de todas las piezas, así como la seguridad de tratamiento de
los eventos adecuados. Con Swing se va un paso más allá, ya que todos los JComponentes son
subclases de Container, lo que hace posible que widgets Swing puedan contener otros
componentes, tanto de AWT como de Swing.
Cuando se empieza a utilizar Swing, se observa que JavaSoft ha dado un gran paso
adelante respecto al AWT. Ahora los Componentes del interfaz gráfico son Beans y utilizan el
nuevo modelo de Delegación de Eventos de Java. Swing proporciona un conjunto completo de
Componentes, todos ellos lightweight, ya no se usan componentes "peer" dependientes del
sistema operativo, y además, Swing está totalmente escrito en Java. Todo ello nos aporta una
mayor funcionalidad en manos del programador, y en la posibilidad de mejorar en gran
medida la cosmética de los interfaces gráficos de usuario.
Son muchas las ventajas que ofrece el uso de Swing. Por ejemplo, la navegación con el
teclado es automática, cualquier aplicación Swing se puede utilizar sin ratón, sin tener que
escribir ni una línea de código adicional. Las etiquetas de información, o "tool tips", se pueden
crear con una sola línea de código. Además, Swing aprovecha la circunstancia de que sus
Componentes no están renderizados sobre la pantalla por el sistema operativo para soportar lo
que llaman "pluggable look and feel", que la apariencia de la aplicación se adapta
dinámicamente al sistema operativo y plataforma en que esté corriendo.
Los Componentes Swing no soportan el modelo de Eventos de Propagación, sino
solamente el modelo de Delegación incluido desde el JDK 1.1; por lo tanto, si se van a utilizar
componentes Swing, se debe programar exclusivamente en el nuevo modelo.
Es muy importante entender y asimilar el hecho de que Swing es una extensión del AWT,
y no un sustituto encaminado a reemplazarlo
8
3.4.- MySQL
MySQL es uno de los Sistemas gestores de Bases de Datos más populares desarrollados
bajo la filosofía de código abierto. La desarrolla y mantiene la empresa MySQL AB pero
puede utilizarse gratuitamente y su código fuente está disponible.
Entre las características disponibles en las últimas versiones de MySQL se puede destacar:
• Amplio subconjunto del lenguaje SQL. Algunas extensiones son incluidas igualmente.
• Disponibilidad en gran cantidad de plataformas y sistemas.
• Diferentes opciones de almacenamiento según si se desea velocidad en las
operaciones o el mayor número de operaciones disponibles.
• Transacciones y claves foráneas.
• Conectividad segura.
• Replicación.
• Búsqueda e indexación de campos de texto.
3.5.- JDBC
JDBC (Java DataBase Connectivity) es un API de Java que permite al programador
ejecutar instrucciones en lenguaje estándar de acceso a Bases de Datos, SQL (Structured
Query Language). Para que una aplicación pueda hacer operaciones en una Base de Datos, ha
de tener una conexión con ella, que se establece a través de un driver, que convierte el
lenguaje de alto nivel a sentencias de Base de Datos. Es decir, las tres acciones principales que
realizará JDBC son las de establecer la conexión a una base de datos, enviar sentencias SQL a
esa base de datos y procesar los resultados obtenidos de la base de datos.
JDBC es una especificación de un conjunto de clases y métodos de operación que
permiten a cualquier programa Java acceder a sistemas de bases de datos de forma
homogénea. Lógicamente, al igual que ODBC, la aplicación de Java debe tener acceso a un
driver JDBC adecuado. Este driver es el que implementa la funcionalidad de todas las clases
de acceso a datos y proporciona la comunicación entre el API JDBC y la base de datos real.
La necesidad de JDBC, a pesar de la existencia de ODBC, viene dada porque ODBC es un
interfaz escrito en lenguaje C, que al no ser un lenguaje portable, haría que las aplicaciones
Java también perdiesen la portabilidad.
El Driver que nosotros utilizaremos será MySQL-connector-java-3.0.14-production que
tiene las siguientes características, nos permitirá trabajar con el sistema de gestor de Base de
Datos escogido que es MySQL.
Es un driver realizado completamente en Java que se comunica con el servidor DBMS
utilizando el protocolo de red nativo del servidor. De esta forma, el driver no necesita
intermediarios para hablar con el servidor y convierte todas las peticiones JDBC en peticiones
de red contra el servidor. La ventaja de este tipo de driver es que es una solución 100% Java y,
por lo tanto, independiente de la máquina en la que se va a ejecutar el programa.
La única desventaja de este tipo de drivers es que el cliente está ligado a un servidor
DBMS concreto. Pero puesto que nuestro servidor DBMS es MySQL, no nos supone ningún
inconveniente.
9
3.6. ECLIPSE
El proyecto Eclipse.org, entre otras muchas cosas, es una plataforma de desarrollo de
aplicaciones Java, que nos permite en todo momento tener controladas todas las Clases y
Paquetes que utiliza nuestra aplicación así como crear proyectos con determinadas
propiedades como Classpath, argumentos de ejecución, etc. Quizá Eclipse no sea la
Herramienta más apropiada para el desarrollo de este programa, pero si que es la que más
conocía, y de la que me resultaba más sencillo su manejo
3.7.- JSmooth
JSmooth, es una aplicación que nos permite crear archivos ejecutables a partir de un
fichero jar. Esta acción elimina una de las principales ventajas de Java que es la
independencia de la plataforma en que se ejecute, pero la he usado por comodidad en la
presentación.
También existen otras aplicaciones que nos permiten pasar de código Java a ejecutables
para otras plataformas.
10
4.- ANÁLISIS
El objetivo de este proyecto es crear una aplicación Servidor-Cliente.
El Servidor lleve a cabo toda la tarea administrativa de nuestro proyecto. Para ello
construiremos una sencilla Base de Datos que pueda contener toda la información necesaria.
Para hacerlo lo menos complicado posible crearemos dos tablas en nuestra base de datos, ya
que considero que es suficiente para manejar la información del Servidor... Todas las tareas
administrativas del Servidor se pueden agrupar en dos grandes grupos:
1. Operaciones con Clientes
2. Operaciones con Trabajos
De hay las dos bases de datos, para las operaciones con clientes y trabajos, crearemos un
campo en la tabla trabajos que referencie a Clientes.
Además de la tarea administrativa, debe llevar a cabo una labor de mantenimiento de esta
Base de Datos, así como un control de los posibles errores que se puedan producir bien en la
transmisión de Datos, o en los accesos de Clientes.
El Cliente por otra parte debe ser lo más autónomo posible, y ser capaz de funcionar sin la
interacción del usuario remoto. Aún así debe disponer de unas funciones mínimas para su
control, como la de ‘parar’ o ‘Continuar’ si el cliente lo desea, así como la opción de
preguntar al usuario antes de establecer la conexión con el Servidor, ya que no todas las
conexiones a Internet son iguales, y puede que el usuario necesite una serie de pasos antes de
conectar.
El programa de Cálculo Intensivo poder ser independiente del programa Cliente que lo
llame, salvo alguna función necesaria para el funcionamiento del cliente que le pasaremos por
una Interface.
Para la comunicación entre Cliente y Servidor son necesarias, o al menos imprescindibles
tres funciones:
1. Descargar Fichero.
2. Enviar Fichero.
3. Registrar Cliente.
Estas son las tres funciones que implementaremos utilizando la tecnología RMI que como
ya he dicho nos permite invocar métodos de forma remota, así pues el código de estas
peticiones estará en el Servidor, y el cliente simplemente las llamará de manera remota.
Aunque el programa Cliente sea lo menos interactivo posible, eso no quiere decir que
debamos ejecutarlo en Background, ya que el usuario puede querer, simplemente por
aburrimiento, comprobar cual es el progreso del programa, es por ello que tanto cliente como
programa de cálculo deben presentar una apariencia lo más vistosa posible.
Por último y para una mayor difusión de nuestro proyecto, ya que nos interesa que el
mayor número de cliente se adhieran a él, nuestro programa cliente debería ser independiente
de la plataforma en que se ejecute. Por ello hemos elegido JAVA para desarrollarlo, ya que
gracias a su portabilidad de clases es posible ejecutarlo desde cualquier máquina, que
disponga eso sí de un entorno JAVA como JRE.
11
4.1.- ANÁLISIS DE LA INTERACCIÓN CLIENTE-SERVIDOR
Como ya he dicho la interacción entre Cliente y Servidor se hará mediante la tecnología
RMI (Remote Method Invocation). Así pues el código fuente de las peticiones que le haga el
Cliente al Servidor, estará contenido en el propio Servidor, mientras que el Cliente únicamente
hace una llamada Remota a dicha petición pasándole unos parámetros necesarios para el
Servidor, y recibiendo un resultado según el resultado de la acción.
La comunicación entre ambos por otra parte debe ser la mínima e imprescindible, para así
no colapsar al Servidor con peticiones que tarden mucho en procesarse, ocupando
innecesariamente los recursos del Servidor. Por tanto estas peticiones serán cortas, y sólo
mantendrán al Servidor ocupado el tiempo mínimo e imprescindible.
Las peticiones imprescindibles que el Cliente necesita hacerle al Servidor para el correcto
funcionamiento del conjunto son las siguientes:
4.1.1. Descargar Fichero :
El Cliente necesita un fichero que contenga los datos que el Servidor necesita
analizar/procesar. Por otra parte el Servidor necesita el login con el que el cliente esta
registrado, para comprobar que realmente está registrado y para actualizar su Base de
Datos. Una vez se establezca la conexión entre ambos ordenadores, el servidor pasara la
petición a otro puerto, para dejar el puerto de aceptación de peticiones libre. Una vez
completada la descarga, el Servidor devolverá al Cliente una cadena de caracteres con el
resultado de la función:
• Nombre del Fichero Descargado La operación ha sido realizada con éxito.
• Error1 : El Servidor no dispone de trabajos para enviar en ese momento. El cliente al
recibir este resultado para inmediatamente su ejecución, ya que en estos momento no
puede hacer nada, e informa al usuario de lo que pasa para que el actúe en
consecuencia.
• Error2 : El Servidor ha detectado un acceso no autorizado, ya que no tiene registrado
este cliente, así que antes de seguir le pide al cliente que se registre. Así que le pide
que se registre de nuevo. El cliente despliega pues el dialogo de registro del cliente.
• Error3 : El Servidor tiene problemas de mantenimiento y avisa al cliente que en ese
momento no puede atender peticiones. El Cliente automáticamente se para y avisa al
Servidor.
• Error : Se ha producido un error, posiblemente ajeno servidor y cliente, durante la
descarga. El cliente es informado, y vuelve a intentar la descarga.
12
4.1.2. Enviar Fichero :
Una vez el Cliente ha completado todo el proceso de cálculo, se dispone a enviar el
fichero donde ha guardado todos los datos obtenidos del análisis. De nuevo el Servidor
necesita unos parámetros para poder llevar a cabo su gestión de la Base de Datos. Los
parámetros son el nombre del fichero, y el login del usuario: el nombre del fichero para
actualizar su registro a completado, y el login del usuario, primero para comprobar que
dicho trabajo estaba asignado a ese usuario, y después para actualizar también el registro
del Cliente. De nuevo una vez actualizada la Base de Datos, el Servidor enviará al Cliente
un entero con el resultado de la operación, este entero puede registrar los siguientes
valores:
• 1 : La operación se ha realizado con éxito.
• 2 : Debido al excesivo tiempo que el cliente ha tardado en completar el trabajo, el
Servidor ha asignado el mismo trabajo a otro Cliente. El Cliente es informado, y
comienza con un nuevo trabajo.
• 3 : El Servidor ha perdido los datos de registro del usuario. Así que le pide que se
registre de nuevo. El cliente despliega pues el dialogo de registro del cliente (En este
caso, puesto que el Cliente tenía que hacer una conexión anterior para descargarse el
fichero de trabajo, el Servidor asume que ha perdido sus datos).
• 0 : El Servidor tiene problemas de mantenimiento y avisa al cliente que en ese
momento no puede atender peticiones. El Cliente automáticamente se para y avisa al
Servidor.
4.1.3. Registrar Cliente :
Antes de empezar a procesar cualquier trabajo, lo primero que debe hacer un nuevo
usuario del programa Cliente, es registrarse en el Servidor. Para tal operación, el cliente
dispone de un diálogo de registro en que el Cliente debe introducir un login (10
caracteres) y su nombre (40 caracteres). En un principio el Programa nos indica si el
Servidor está disponible en ese momento, si el así rellenamos los campos y enviamos la
petición al Servidor. Los parámetros son los dos campos que acabamos de rellenar: login y
nombre. El Servidor una vez registrado el nuevo usuario nos retorna un entero con el
resultado de la operación. Los posibles resultados son:
• 1 : La operación se ha realizado con éxito, El Servidor nos ha registrado como nuevo
usuario.
• 2 : Ya existe un Cliente con ese login: El Cliente es informado y pide al usuario que
introduzca un login diferente para poder registrarse.
• 0 : Se ha producido un error en el servidor: El Cliente informa al usuario de que el
Servidor tiene problemas y le pide que lo intente más tarde.
Con estas tres funciones, quedan cubiertas todas las demandas que el Cliente pueda
requerir del Servidor y viceversa.
4.2 ANALISIS DEL CLIENTE
Como ya he explicado, la aplicación Cliente debe ser un programa capaz de ejecutarse sin
la interacción del usuario, ya que esa es la idea de la computación zombi, aprovechar la
capacidad de procesamiento de un ordenador, cuando éste está encendido pero sin realizar
ninguna tarea.
Aun así lo ideal seria que el programa tuviese unos parámetros de configuración mínimos
accesibles al usuario como por ejemplo poder parar o reanudar la ejecución del programa en
cualquier momento, o bien pedir al programa que éste nos pida autorización siempre antes de
conectarse a la red. Además de esto sería interesante que con un solo vistazo, el usuario
pudiera comprobar sus propias estadísticas, así como el progreso que esta siguiendo el
programa de cálculo intensivo.
13
Para llevar un registro de las estadísticas hay que guardar los datos permanentemente en
un fichero al que el Cliente pueda acceder cada vez que se inicie. Estos datos, así como un
registro de todos los sucesos que vayan sucediendo durante la ejecución del Cliente, se
guardaran en cada iteración para no perder todos los datos en caso de un fallo del sistema.
También el programa tiene que mantener un control sobre la disponibilidad del Servidor,
y, si por cualquier motivo cayera el Servidor, o no pudiera atender las peticiones, el Cliente
tiene que detectarlo, notificar al usuario de lo que esta ocurriendo (para que pueda actuar en
consecuencia cuando vuelva) y parar la ejecución del programa, o al menos llevar una política
de parar una vez intentada la operación n veces cada x minutos.
Por último el Cliente debe detectar cualquier error que pueda generar el propio cliente y
notificarlo al usuario, como por ejemplo, perdida de datos, perdida de algún fichero...
Así pues nuestro programa Cliente constará de tres partes bien diferenciadas:
4.2.1.
Bucle Principal:
El Bucle principal, como su nombre indica es un Bucle infinito que el sólo y sin la
interacción de ningún usuario pueda ir Descargando datos (Petición remota de Descarga al
Servidor), Procesándolos (Iniciando el Thread de Cálculo Intensivo), y Enviándolos al
Servidor (Petición remota de envío al Servidor), llevando de todo ello un registro que el
usuario pueda consultar en cualquier momento. También controla en cada iteración que no
se haya producido ningún error, y si es así comunicarlo al usuario.
4.2.2.
Interficie Gráfica:
Aunque el Bucle puede realizar todo el trabajo, en condiciones óptimas, sin ayuda del
usuario, no está de más permitir que el usuario interaccione con el programa. Pueda parar
y reanudar el programa, decidir el modo de conexión del programa, ver sus estadísticas,
ver que sucesos han ocurrido en su ausencia, ver el progreso actual del Cálculo y
sobretodo enterarse si todo ha funcionado de forma correcta mientras el no estaba. Para
poder parar y reanudar el programa en cualquier momento Bucle principal y Programa de
Cálculo Intensivo son Threads.
4.2.3
Programa de Calculo Intensivo:
Nuestro programa Cliente será compatible con cualquier programa de Calculo que
podemos introducir siguiendo unas mínimas reglas de comunicación entre ambos: El
Programa de Cálculo tiene que poder comunicar al Prog. Cliente que ha finalizado, que
está en pausa, que se reanuda, o bien que se ha producido un error durante su ejecución.
Del mismo modo el Prog Cliente tiene que poder decirle al Prog de Cálculo cuando
pararse, y cuando reanudar su ejecución, así como proporcionarle un espacio en la pantalla
donde poder mostrar el estado actual de su proceso.
14
4.3. ANÁLISI DE LA APLICACIÓN SERVIDOR:
Para analizar el programa Servidor en su conjunto, dividiremos su contenido en tres
secciones:
1. La Base de Datos que necesita para poder gestionar correctamente toda la
información.
2. Las Funciones Remotas
3. La Interficie Gráfica.
4.3.1.- BASE DE DATOS
La Base de Datos que necesita nuestro Servidor es muy sencilla, ya que la escasa
complejidad de los Datos que maneja no requiere algo más elaborado.
Básicamente el Servidor maneja dos grandes Clases de Información:
1.- Información sobre Clientes:
2.- Información sobre Trabajos:
En consecuencia es lógico crear únicamente dos Tablas en nuestra BD, una que
guarde la información sobre cada trabajo disponible, asignado o completado en nuestro
servidor, y otra que guarde los datos de los clientes registrados en él mismo.
La información que necesitamos conocer sobre cada una de estas clases tampoco debe
ser muy amplia.
De los Trabajos necesitamos: El nombre del fichero asociado, Su prioridad, Su Estado
actual, es decir, Pendiente de asignación, asignado a Cliente o Completado, El cliente al
que está asignado, o por el que ha sido completado, su fecha de asignación o finalización,
y su ubicación en el disco duro.
De los Clientes únicamente necesitamos : Su login, Su Nombre, El nº de trabajos que
ha completado con éxito, y la fecha de su ultima conexión.
Con estos sencillos datos el Servidor podrá llevar a cabo un control de toda la
información que necesita. Para ello necesitamos un conjunto de consultas SQL con las que
podamos acceder rápidamente a todos los datos de todos los trabajos y clientes que
guardamos, añadir nuevos clientes, añadir nuevos trabajos, actualizar el estado de un
trabajo, incrementar los trabajos completados de un cliente o su fecha de conexión, borrar
un trabajo, listar los trabajos según su estado, prioridad, fecha..., etc...
Para esto usaremos el API de JDBC que nos permite ejecutar sentencias SQL en un
entorno JAVA.
4.3.2 FUNCIONES REMOTAS
Ya hemos descrito las funciones remotas en el punto de Interacción Cliente-Servidor.
Para resolver la comunicación de dichas funciones con la Interficie gráfica del Servidor,
crearemos una Interface a para que la funciones remotas puedan también comunicar sus
resultados al administrador del Servidor
Esta Interficie constará de las siguientes funciones:
Incrementar y Decrementar las peticiones de Descarga, Transferencia y Registro,
enviar un mensaje al Servidor, enviar un mensaje urgente, informar de que ha realizado
una operación en la Base de Datos con éxito, y informar de que ha realizado una operación
en la Base de Datos que no ha salido bien.
Con estas funciones y las que hemos hecho sobre la Base de Datos, las funciones
remotas podrán llevar a cabo el control de la Base de Datos, y comunicarse con el
administrador.
También hay que tener en cuenta, que para la Descarga/Transferencia de ficheros, no
podemos usar el mismo puerto que el que usamos para aceptar las peticiones, ya que
podemos tenerlo ocupado más tiempo del necesario limitando así las peticiones que
podríamos aceptar.
15
4.3.3 INTERFICIE GRÁFICA
Como ya he dicho el administrador del Servidor tiene que poder comprobar el estado
actual del Servidor sólo con echar un simple vistazo a la pantalla.
Tiene que saber si se ha producido un error crítico, se ha caído el Servidor, se ha
perdido la conexión con al Base de Datos, se ha desconectado MySQL, hemos perdido el
registro en el Servidor RMI... cualquiera de estos errores hacen que el Servidor no pueda
cumplir su función y tenga que ser reparado inmediatamente para poder seguir atendiendo
peticiones.
El administrador también tiene que poder consultar todas las tablas de la Base de
Datos de forma rápida y dinámica, y consultarla en un orden especifico para su mayor
comodidad. Por eso toda la base de Datos debe estar visible en todo momento, y si no es
así accesible rápidamente.
La Base de Datos requiere también un mantenimiento, que el administrador debe
poder efectuar de manera clara y desde la misma Interficie, por ello debemos diseñar
diálogos que permitan efectuar todas las operaciones necesarias sobre la Base de Datos
como: Añadir nuevos trabajos, Borrar Trabajos Pendientes, Cambiar la Prioridad de un
Trabajo Pendiente, Comprobar la consistencia de la Base de Datos, o Consultar los datos
de cualquier Trabajo, es decir, comprobar que cada trabajo tiene su archivo de Datos
asignado. También debe saber cuando un trabajo lleva demasiado tiempo asignado, por lo
que se retrasa su procesamiento, y poder asignarlo a un nuevo usuario para que este lo
complete. Esta última función debería realizarse automáticamente todos los días una vez y
cambiar el estado de estos trabajos a pendiente con máxima prioridad.
Por último el administrador tiene que mantener un historial de todo lo que sucede con
el Servidor a lo largo de su ejecución para poder consultarlo en el futuro, para ello hay que
proporcionarle una forma ya sea automática o manual de poder guardar ficheros con el
estado actual de la Base de Datos, y del los Sucesos que registra el Servidor, asimismo
también hay que proporcionarle una herramienta gráfica con la que poder consultar esos
archivos en el futuro.
16
5.- DISEÑO
5.1.- DISEÑO DE LAS FUNCIONES REMOTAS:
Interface que le pasamos al Cliente mediante el fichero Servidor_Skel.class
String descargaFitxer (String user)
int enviarFitxer (String user, String nomFitxer)
int registrarUser (String user, String nom)
Estas son las funciones remotas a las que el Programa Cliente tendrá acceso mediante la
Interface Remota ServidorI.class
5.1.1 Protocolo de Transferencia
Puesto que las funciones de Descarga y Transferencia de fichero Requieren el envío de
ficheros a través de la red, ya que un fichero no se puede pasar por parámetro, ni enviar como
resultado, Es preciso que el cliente implemente además de una Interface con el Servidor dos
clases capaces realizar la transferencia de ficheros con el servidor a través de sockets.
Estas dos clases deben ejecutarse conjuntamente con la función remota pero en diferentes
hilos de ejecución, por ello extenderán la clase Thread.
Una vez tenemos ambas clases sólo nos restará crear un protocolo de transporte común a
Servidor y Cliente para que se envíen los Datos.
Estos son los protocolos una vez aceptada la petición inicial:
Protocolo de Descarga:
Servidor envía el nuevo puerto de Escucha
Cliente recibe nuevo puerto
Cliente envía ACK
Servidor recibe ACK
Cliente pide la conexión al nuevo puerto de escucha
Servidor acepta conexión
Mientras quede fichero
Servidor envía Fichero
Cliente recibe fichero
Cliente envía ACK
Servidor recibe ACK
Fmientras
Protocolo de Transferencia:
Servidor envía el nuevo puerto de Escucha
Cliente recibe nuevo puerto
Cliente envía ACK
Servidor recibe ACK
Cliente pide la conexión al nuevo puerto de escucha
Servidor acepta conexión
Mientras quede fichero
Cliente envía Fichero
Servidor recibe fichero
Servidor envía ACK
Cliente recibe ACK
Fmientras
17
La implementación de estas funciones se encuentra en el Servidor, y el Servidor accederá
a ellas a través de la clase generada por RMI Servidor_Stub.class.
El pseudocódigo de estas funciones es el siguiente:
5.1.2. Servidor.java
Variables:
interficie: nos permite tener acceso a la interficie Gráfica del Servidor
socketServidor : es el socket que acepta las peticiones.
String descargaFitxer(String user) {
Result = ‘ERROR3’
Incrementamos las peticiones de Descarga en curso a través de interficie.
Aceptamos la petición del cliente a través de socketServidor
Creamos un nuevo socketServidor y enviamos al cliente en el que estamos escuchando,
dejando así libre el de aceptación de peticiones.
Si (user existe en nuestra Base de Datos) entonces
Cogemos un nuevo Trabajo de la Tabla Treballs
Si (Trabajo /= null) entonces
Si existe el directorio ‘Treballs’
Enviamos trabajo al Cliente
Cerramos sockets
Si se ha producido ningún error
Informamos al Servidor a través de interficie
Sino
Actualizamos el trabajo en la base de datos
Estado = asignado
Login = user
Data = fecha de hoy
Informamos al Servidor de los Cambios Realizados en la BD.
Result = nombre del Trabajo
Fsi
Si hay algún error en la BD
Devolvemos el trabajo a su estado anterior
Informamos al Servidor del Error
Fsi
Sino
Crear directorio ‘Treballs’
Informar al servidor que se han perdido todos los ficheros asociados a
trabajos.
Fsi
Sino
Result = ERROR1
Informa al Servidor de que la BD no dispone de Trabajos para enviar.
Fsi
Sino
Result = ERROR2
Informa al Servidor que un cliente no autorizado ha intentado la conexión
Fsi
Control de Excepciones:
Si se produce alguna excepción Informar al Servidor del problema
Fin control de Excepciones
Decrementar las peticiones de Descarga en curso
Retornar (Result)
}
18
int enviarFitxer(String user, String Trabajo) {
Result = 0;
Incrementar peticiones de Transferencia en curso
Aceptamos la petición del cliente a través de socketServidor
Creamos un nuevo socketServidor y enviamos al cliente en el que estamos escuchando,
dejando así libre el de aceptación de peticiones.
Si (user esta registrado)
Si ( trabajo está asignado a user)
Si no existe directorio ‘Completats’
Crear directorio y Informar al Servidor que se han perdido ficheros
Completados
Fsi
Recibimos el Fichero
Cerramos sockets
Actualizamos el trabajo en nuestra BD
Estado = asignado
Login = user
Data = fecha de hoy
Informamos al Servidor del resultado
Borramos el trabajo de su antigua ubicación
Result = 1
Si se produce algún error durante la descarga
Devolver el trabajo a su estado anterior
Informar al Servidor del error
Fsi
Sino
Result = 2
Informar al Servidor de que se había asignado el trabajo a otro user
Fsi
Sino
Result = 3
Informar al Servidor de la perdida del registro del cliente
Fsi
Control de Excepciones:
Si se produce alguna excepción Informar al Servidor del problema
Fin control de Excepciones
Decrementar las peticiones de Transferencia en curso
Retornar (Result)
}
int registrarUser (String user, String nom) {
Result = 0
Incrementar peticiones de Registro en curso
Si user no está registrado
Guardar nuevo usuario en la BD
Result = 1
Sino
Informar al Servidor de la repetición de login
Result = 2
Fsi
Control de Excepciones:
Si se produce alguna excepción Informar al Servidor del problema
Fin control de Excepciones
Decrementar las peticiones de Registro en curso
Retornar (Result)
}
19
5.2.- DISEÑO DEL CLIENTE
Las tres partes del Cliente, Bucle Principal, Programa de Cálculo e Interficie Gráfica
tienen que poder comunicarse a través de variables Globales para conocer en todo momento el
estado del Programa así como otros datos necesarios para su ejecución.
Creamos la Clase Dades.java que contendrá estas variables así como las funciones
necesarias para acceder a ellas. Todas estas variables y funciones serán estáticas, es decir
ocuparan siempre el mismo lugar en memoria, para que todas las clases puedan acceder a ellas
en todo momento
Dades.java
Variables Globales:
Aturat : indica si el programa está parado o en ejecución.
Intents : nº de intentos de conexión fallidos antes de parar el programa.
Mode: indica el modo en que trabaja el programa (si pide autorización al conectar
o no).
Estat: estado actual del programa.
Los valores de esta variable serán:
ACABAT ->
Listo para Descargar
REBENT ->
Descargando Fichero
INICI ->
Listo para Procesar
EXECUCIO -> Procesando
PAUSA ->
Programa de Cálculo en pausa
FI ->
Listo para Transferir
ENVIANT ->
Transfiriendo fichero
User: login del usuario.
NomUser: nombre del usuario.
Servidor = servidor actual al que nos conectamos.
TempsCPU = tiempo de CPU total consumido.
TempsTransf = tiempo total consumido en operaciones de transferencia de ficheros.
NumTreballs = nº de trabajos completados por el usuario.
NomFitxer = nombre del Trabajo actual que se está procesando.
serverDefault = Servidor por defecto. Se carga al iniciar el programa a partir del
fichero ‘server’
Funciones Globales
Además de las funciones para modificar o acceder a cualquiera de estas variables.
IniDades :
Inicializa los valores de las variables a partir del Fichero ‘Data’ donde guardamos los
valores de las variables para no perderlos
CrearDades :
Crea el fichero ‘Data’ e inicializa por defecto todas las variables. Esta función sólo se
utiliza en la primera ejecución del Programa, o en caso de perdida del fichero ‘Data’.
SalvarDades :
Guarda en el Fichero ‘Data’ todas las variables, Esta función se realiza al apagar el
programa, y también en cada iteración del Bucle principal, para que en caso de fallo
del sistema no lo perdamos todo.
Con estas funciones ya podemos llevar un control del programa desde todos sus diferentes
bloques.
20
5.2.1.- DISEÑO DEL BUCLE PRINCIPAL
Como ya he explicado el bucle principal es un bucle infinito que se limita a ir
descargando trabajos, procesándolos y enviándolos al Servidor, todo ello comprobando en
cada iteración que no se produzca ningún fallo en la conexión con el cliente, o bien algún
fallo de perdida de los datos que el Cliente necesita para funcionar.
Además de esto proporcionamos una serie de funciones en la interficie gráfica para
que a través de las variables globales, ésta pueda interactuar con el bucle principal, así por
ejemplo si el usuario para el programa con a través de la interficie gráfica, esta pone la
variable ‘aturat’ a true, con lo que el bucle principal se pararía hasta que el usuario le
indicara que continuase.
La manera mas fácil de parar el bucle es poner la variable ‘aturat’ a true y en cada
iteración del bucle comprobar el valor de la variable. Si es true, suspendemos el programa
hasta nuevo aviso.
Así pues el programa principal será un bucle que en cada iteración comprobará en que
‘estat’ se encuentra el programa, y según el estado ejecutará una de sus tres funciones. Al
final de cada iteración, comprobará que no se haya producido ningún error grave como
perdida del Registro, perdida de los Datos, indisponibilidad del Servidor, y si no es así
continuará. En caso de necesitar conectarse con el Servidor, el programa comprobara el
modo de trabajo del Cliente, si no necesita autorización, continuará, si la necesita, parará
el programa en espera de que el usuario actúe. Para ello dotaremos al Bucle de varios
diálogos para que pueda interactuar con el cliente de forma clara.
Los diálogos serán los siguientes:
5.2.1.1. DialogNoConexio.java
En caso de que el Servidor no esté disponible, el Bucle principal pasará a
estado inactivo durante 10 minutos, pasados estos 10 minutos reintentará la
conexión. Este proceso lo realizará un total de 5 veces (variable ‘intents’) antes
de parar el programa.
Este Diálogo es simplemente informativo, informa al usuario de lo que esta
sucediendo y le muestra al usuario el nº de intentos que faltan para parar el
programa. También informa de que si el usuario quiere prescindir de este proceso,
parar el programa e intentarlo mas tarde, tiene que cerrar este dialogo y parar el
Programa.
5.2.1.2. DialogFiIntents.java
Una vez que se han agotado los 5 intentos de conexión, el programa se para.
Este Diálogo, también informativo comunica al usuario que el programa ha
agotado los 5 intentos de conexión y se ha parado.
5.2.1.3 DialogError.java
Cuando el Bucle detecta algún error, como puede ser la perdida de un fichero,
un error en la transferencia, etc... informa al usuario a través de este diálogo. Que
simplemente informa del error. Si no es un error crítico, el programa sigue con su
ejecución normal. Para informar del error, le pasamos como parámetro un String
donde se vea reflejado.
21
5.2.1.4 DialogConfirmacio.java
Antes de cada operación de transferencia el Bucle comprueba cual es el modo de
trabajo del Cliente (Variable global ‘mode’). Si el modo es ‘Sin pedir autorización’
continúa, en caso contrario, el Bucle se detiene y muestra este diálogo.
El diálogo de Confirmación pide al usuario si quiere que el Cliente se conecte
a internet para iniciar una operación de transferencia, dándole a este dos opciones:
1. Conectar -> En cuyo caso se cierra el diálogo y el bucle continúa con su
ejecución
2. Aturar -> En cuyo caso el bucle continúa suspendido a la espera de nuevas
instrucciones del usuario.
5.2.1.5. DialogPerduaRegistre.java
Si tras una de las peticiones al Servidor, éste nos indica que ha perdido
nuestro registro. El Bucle al final de cada iteración comprueba que si esto ha
pasado, en tal caso suspende la ejecución del Bucle y nos muestra este Diálogo.
Este Diálogo, como el de Registro, pide al usuario que introduzca los datos de
registro (login y nombre). Una vez ha rellenado los campos, el usuario tiene 3
opciones:
1. Enviar -> El Cliente ejecuta la función remota ‘registrarUser’. Y a través
del display inferior del mismo diálogo informa del resultado de la
operación.
2. Acceptar -> Si ya ha sido registrado, se cierra el diálogo y el usuario
puede continuar con la ejecución del programa manualmente.
3. Cancelar -> El usuario decide no registrarse en ese momento, con lo que
cada vez que intente un acceso al servidor se le volverá a mostrar el
mismo diálogo.
5.2.1.6. DialogNoTreballs.java
Es un tipo de error con un tratamiento especial. Cuando la petición de
descarga nos retorna este resultado. El Bucle principal opta por suspender el
programa y mostrar este diálogo.
Este diálogo sólo informa de que el Servidor no puede ofrecernos trabajo y
que la mejor opción seria finalizar el programa y volver a ejecutarlo mas tarde.
Además de estos diálogos, el usuario puede llevar un registro de todo lo que va
sucediendo durante la ejecución del programa. Para ello la interficie grafica proporciona
un cuadro de texto donde el Bucle va anotando todos los sucesos.
Para la ejecución del Programa de Cálculo intensivo proporcionaremos al paquete
Cliente una Interface con la que poder comunicarse. Esta Interface lo único que contendrá
será la función que pone en marcha el programa de Cálculo.
int Simula();
Puesto que este bucle es un programa que necesitaremos parar o reanudar a nuestro
gusto desde la misma interficie gráfica incluso, y que además queremos que se ejecute
concurrentemente con todos los eventos que la interacción del usuario pueda generar, lo
ideal es que esta clase sea también un Thread, y además que sea una variable estática, es
decir que siempre ocupe el mismo lugar en memoria para que así se pueda acceder a ella
desde todas las clases.
Una vez sentadas estas bases procedemos a ver el pseudocódigo del Bucle Principal:
22
5.2.1.7. Bucle.java
Variables:
Disponible -> Indica si el servidor está disponible o no.
PerduaReg -> Indica si hemos perdido el registro o no.
//No olvidemos que además de estas tenemos todas las variables globales.
Bucle principal
Mientras (true) hacer
Si aturat = true
Suspender Ejecución
Fsi
Switch (estat)
Caso ACABAT:
Si mode = 0
Mostrar DialogConfirmacio
Suspender Ejecución
Fsi
Si aturat = false
Conectar con el Servidor
Comprobar que Servidor RMI está en marcha
Disponible = true
Estat = REBENT
Ejecutar Thread Receptor
Resultado = Petición remota de Descarga de fichero
Switch (resultado)
Caso ‘ERROR’
Estat = ACABAT
Aturat = true
Informar usuario
Caso ‘ERROR1’
Estat = ACABAT
Aturat = true
Informar al usuario
Mostrar DialogNoTreballs
Caso ‘ERROR2’
Estat = ACABAT
Aturat = true
Informar al usuario
Mostrar DialogPerduaRegistre
Caso ‘ERROR3’
Estat = ACABAT
Aturat = true
Informar al usuario
Por Defecto
Estat = INICI
NomFitxer = resultado
Informar al usuario que la operación se ha realizado con éxito
Fswitch
Fsi
Control de Excepciones:
No se puede establecer la conexión
Estat = ACABAT
Disponible = false
Informar al usuario del tipo de Problema.
Otras excepciones
Estat = ACABAT
23
Informar al usuario del tipo de Problema.
Mostrar DialogError
Fcontrol de Excepciones
Caso INICI:
Si existe el fichero de Datos
Estat = EXECUCIO
Simula()
Sino
Estat = ACABAT
Informar al usuario
Fsi
Control de Excepciones
Si se produce algún problema
Estat = ACABAT
Informar al usuario
Fsi
Fcontrol
Caso FI
Si mode = 0
Mostrar DialogConfirmacio
Suspender Ejecución
Fsi
Si aturat = false
Si existe el Fichero de Resultados
Conectar con el Servidor
Comprobar que Servidor RMI está en marcha
Disponible = true
Estat = ENVIANT
Ejecutar Thread Emisor
Resultado = Petición remota de envío de fichero
Switch (resultado)
Caso 0:
Aturat = true
Estat = FI
Informar al usuario
Caso 2:
Aturat = true
Estat = ACABAT
Informar al usuario
Caso 3:
Estat = FI
PerduaReg = true
Informar al usuario
Caso 1:
Estat = ACABAT
Informar al usuario que el envío se ha realizado con éxito.
Fswitch
Sino
Estat = INICI
Informar al usuario que volvemos a procesar el trabajo
Fsi
Fsi
24
Control de excepciones
No se puede establecer la conexión
Estat = FI
Disponible = false
Informar al usuario del tipo de Problema.
Otras excepciones
Estat = FI
Informar al usuario del tipo de Problema.
Mostrar DialogError
Fcontrol de Excepciones
Fswitch
Guardar copia del Registro
SalvarDades
Si no hay perdida de Registro
Si Servidor disponible
Intents = 5
Sino
Si intents > 0
Mostrar DialogNoConexio
Informar al usuario
Intents -Dormir 15 minutos
Sino
Aturat = true
Mostrar DialogFiIntents
Informar al usuario
Intents = 5
Fsi
Fsi
Sino
Aturat = true
Mostrar DialogPerduaRegistre
Fsi
Fmientras
Fbucle Principal
25
5.2.2 DISEÑO DE LA INTERFICIE GRÁFICA DEL CLIENTE
Para la implementación de toda la interficie gráfica, así como de todos los
componentes gráficos del programa Cliente, tales como los Diálogos descritos en el
apartado anterior, o la visualización del progreso del Programa de Cálculo usaremos la
librería de JAVA Swing que es mucho mejor que el AWT como ya hemos explicado en el
apartado 3.
La interficie que permitirá al usuario interactuar con el Cliente debe ser lo más clara y
sencilla posible, e incluir únicamente aquellas opciones que sean imprescindibles para el
manejo del Programa.
Como ya he dicho estas opciones serán
1. Continuar
Continuará con la ejecución del programa Cliente.
2. Parar
Detendrá la ejecución del programa Cliente.
3. Configuración
Permitirá modificar el modo de trabajo del Programa, así como si el usuario lo
desea cambiar el servidor al que nos conectamos.
(La opción de cambiar el servidor no tendría por que existir, ya que se supone que
el servidor será siempre el mismo, pero es mucho más cómoda para poder ejecutar
el Servidor en cualquier máquina.)
Además de estas tres opciones para controlar el programa el usuario tiene que ver en
todo momento, si lo desea, sus propias estadísticas, un registro de los sucesos que
acontecen en el programa, y por supuesto el progreso del Programa de Cálculo Intensivo.
Así pues el componente gráfico principal de nuestro Cliente será un JFrame o
Ventana sobre el que colocaremos toda la información que hemos ido mencionando.
Dividiremos la ventana en dos Secciones. La de arriba será la sección de Control del
Programa Cliente, y la de abajo la utilizaremos para visualizar el progreso del Programa
de Cálculo Intensivo.
Ambas secciones serán JPanels. El JPanel inferior será una clase importada del
Paquete (package) calculIntensiu, así nos aseguramos que cualquier otro programa que
queramos implementar para nuestro Cliente sea compatible definiendo un JPanel sobre el
que visualizar su progreso.
26
La sección de control se dividirá en tres partes, sólo una de ellas servirá para la
interacción con el usuario, las otras dos serán simplemente informativas:
5.2.2.1. PanelDaltEsqEtiqs.java
Este panel situado a la izquierda mostrará información sobre los datos del usuario, así
como las estadísticas que este ha acumulado desde que posee el programa Cliente.
Los Datos se mostrarán en JLabels y serán:
Estado del Programa
Servidor
Estado actual del Cliente
Login del Cliente
Nombre del Cliente
Trabajos Completados
Trabajo actual en Proceso
Tiempo Total de CPU
Tiempo total de Transferencia
Además este Panel proporcionará una función al resto de clases del mismo package
para que puedan actualizar dicha información a partir de la JLabel que quieren
modificar. No se pueden modificar directamente las etiquetas desde otras clases, hay
que modificar la Variable Global que nos muestran, y después indicar que etiqueta
queremos actualizar.
Tanto las etiquetas como la función que las modifica son estáticas, es decir ocupan el
mismo sitio en memoria siempre.
5.2.2.2. PanelDaltDret.java
Por último este panel situado a la derecha del todo muestra un registro de los sucesos
que van pasando durante la ejecución del Cliente.
El panel consta de un JScrollPane en el que visualizamos un área de Texto JTextArea
donde desde el Bucle y desde algunos Diálogos vamos escribiendo todo lo que va
pasando.
Para escribir los sucesos, este panel proporciona una función
afegirText(String).
Tanto la función como el Área de texto son estáticos.
También nos proporciona una función con la que guardar el contenido del Área de
texto en un archivo de Log
27
5.2.2.3. PanelDaltEsqBotons.java
Este panel es el único que permite la interacción del usuario. Estará en el centro del
panel Superior.
Consta de tres botones bastante claros acerca de su cometido. Continuar, Parar,
Configuración. Al constructor de este panel se le pasa como complemento una
referencia al Bucle Principal del programa, ya que desde este panel debemos ser
capaces de reanudarlo, no así de pararlo, así nos aseguramos de que el Bucle principal
acabe un ciclo antes de pararlo.
Para que el usuario tenga mas fácil y claro lo que está haciendo la función de
Configuración se presenta a través de un Diálogo. Ese diálogo sólo se podrá mostrar
con el programa detenido.
El pseudocódigo de este panel es el siguiente:
Constructor (Bucle Principal bucle)
Inicializa componentes
Añadir JButton Continuar
Añadir JButton Parar
Añadir JButton Configuración
Continuar.procesar Evento
Si aturat = true
Aturat = false
Reanudar el Thread Bucle.java
Sino
Mostrar DialogError
Fsi
Parar.procesar Evento
Si aturat = false
Aturat = true
Sino
Mostrar DialogError
Fsi
Configuración.procesar Evento
Si aturat = true
Mostrar DialogConfiguracio
Sino
Mostrar DialogError
Fsi
Fin Constructor
5.2.2.4. DialogConfiguracio.java
Este Diálogo tiene los siguientes componentes:
Campo de Texto JTextField para introducir el nuevo Servidor
Un JButton que recupera el servidor por defecto, almacenado en el fichero ‘Data’.
Un grupo de 2 opciones: (los dos modos de Trabajo del Cliente)
Opción 1 - > Consultar antes de conectar
Opción 2 -> Conectar sin consultar
Dos JButton más
Aceptar -> Guarda los cambios realizados y cierra el Diálogo
Cancelar -> Cierra el Diálogo sin guardar los cambios realizados
28
Además de las dos Secciones principales la ventana principal tendrá dos Diálogos
más:
5.2.2.5. DialogFinal.java
Este diálogo se muestra cuando pulsamos el comando de cerrar la ventana.
Únicamente nos pregunta si estamos seguros de querer finalizar el Programa. Y nos da
dos opciones:
1. Si -> Con lo que llamamos al DialogClose que se encarga de cerrarlo todo y
guardar los datos
5.2.2.5.1. DialogClose.java
Guarda el registro, Salva las Variables Globales (SalvarDades()) y sale de la
aplicación.
2. No -> Vuelve a la ejecución
Este diálogo sólo lo podemos mostrar con el programa parado, en caso contrario el
Cliente nos indica que se ha producido un Error y nos muestra el DialogError.
5.2.2.6. DialogPerduaDades.java
Este diálogo se muestra si al arrancar el programa cliente se detecta que el fichero
donde guardamos los datos ‘Data’ ha desaparecido. El programa reacciona con la
función crearDades() que inicializa todas las variables, pero el login y el nombre del
usuario son desconocidos para el, por ello le pide al usuario que vuelva a introducir
estos datos.
Este diálogo consta pues de dos campos de texto uno para el login y otro para el
nombre, un botón de aceptar, con el que guardamos los Datos en el archivo y como
variables globales, cerramos el dialogo e indicamos al usuario que puede continuar
con la ejecución del programa manualmente.
Si no rellenamos correctamente los campos, dejamos alguno vacío, en la parte inferior
del diálogo hay un display que nos lo indica.
Todos los diálogos que hemos mencionado hasta ahora, que por si no lo he
mencionado todavía son JDialogs, son diálogos modales, es decir mientras estén visibles,
la ventana principal del programa, el JFrame está inactivo, es decir que no se puede
acceder a el hasta que no se cierre el Diálogo.
Además de la ventana principal dentro de la interficie gráfica, aunque no dependientes
de la ventana principal encontramos dos diálogos más. Estos dos Diálogos son
independientes de la ventana porque ésta no todavía no esta construida cuando los
mostramos, ya que ambos diálogos son causa de, o bien un error durante el arranque del
programa, o bien la primera ejecución del programa:
5.2.2.7. DialogNoArranc.java
Este diálogo se muestrea si durante la carga de la interficie Gráfica (JFrame principal),
o del Bucle Principal se detectan errores imposibles de solucionar. Excepcions
Esta Diálogo nos indica que no puede cargar el programa, y nos invita a salir e
intentarlo mas tarde a través del botón ‘Salir’
29
5.2.2.8. DialogRegistre.java
Este diálogo es muy similar al DialogPerduaRegistre, por no decir idéntico. Este
dialogo se carga cuando desde el programa principal detectamos la ausencia del
fichero ‘Config.ini’ que es un chivato que nos indica si la aplicación se ha ejecutado
alguna vez o por el contrario esta es la primera.
Este JDialog consta de cuatro partes:
1. Mensaje de bienvenida para el nuevo usuario.
2. En esta parte aparecen dos Campos de texto con sus respectivas etiquetas, uno
para introducir el login, y otro para el nombre del usuario.
3. Un pequeño display donde se muestra el resultado de la petición de registro
4. Dos botones cuyas funciones describiremos a continuación:
- Registrarse:
Si estamos conectados
Si los dos campos están llenos
Resultado = enviar petición de registro
Switch (Resultado)
Caso 0
Informamos en el Display de que el Servidor no puede atendernos en este
momento.
Caso 1
Informamos en el Display de que estamos registrados como nuevos
clientes.
CrearDades()
Aceptado = true;
Caso 2
Informamos en el Display que ese login ya existe
Fswitch
Control de excepciones
No se puede establecer la conexión
Informamos en el Display que el Servidor no está disponible.
Otras excepciones
Informamos en el Display que no se puede realizar la operación.
Fcontrol de Excepciones
Sino
Informamos en el Display que hay que llenar los dos campos.
Fsi
- Comenzar:
Si aceptado = true
Crear fichero ‘Config.ini’
Cargar el Programa Cliente
Control de Excepciones
Informamos en el Display que se ha producido un error en el arranque.
Fcontrol
Sino
Informar en el Display que antes de empezar hay que registrarse.
Fsi
Si al cargar el Diálogo el cliente detecta que en ese momento el servidor no está
disponible, informa en el Display.
Por último nos dejamos un Thread que está en continua ejecución desde el inicio del
programa que simplemente se encarga que ir actualizando las variables globales
tempsCPU y tempsTransfer. Este Thread es Temps.java.
30
5.2.3.- DISEÑO DEL PROGRAMA DE CÁLCULO INTENSIVO
El Programa de Cálculo intensivo que diseñemos debe constar de dos partes: El
programa en sí que efectúa todos los cálculos necesarios para analizar los datos que
obtiene del fichero ‘Treball.dat’. Y la visualización gráfica del progreso del Cálculo.
Para la visualización gráfica tenemos que implementar una clase que extienda la clase
JPanel y que para ser compatible con el package client debe llamarse PanelCalcul.java.
En este panel el programa principal de cálculo irá reflejando lo que vaya haciendo.
Este panel, se carga por defecto junto con toda la interficie Gráfica del programa
Cliente, así que genera algún error al cargarse, el programa Cliente no se cargará.
El programa principal de Cálculo que he escogido es un Simulador de Incendios.
Existe un Territorio de 300 x 270 píxeles al que le afectan una serie de factores (Datos
a analizar);
Riesgo de Incendios
Nº de incendios por año
Crecimiento de la vegetación
Capacidad de extinción de lo Bomberos
Probabilidad de fallo humano
Por cada año (iteración) se realizan las siguientes operaciones:
1. Se recorre cada píxel y si no tiene vegetación se deja crecer según la media de
crecimiento
2. Se ponen sin vegetación todos los píxeles quemados el año anterior.
3. Mientras queden incendios
3.1. Se elige un píxel
3.2. Si tiene vegetación y supera el riesgo de incendio, se incendia
3.3. El incendio se propaga a los píxeles vecinos según la intensidad del
incendio, los píxeles quemados de alrededor, y la meteorología de ese
año.
3.4. En cada nueva propagación si los bomberos tienen capacidad y no hay
ningún fallo humano, el incendio se apaga.
Al final del Programa se guardan una serie de Datos que se han ido calculando durante
la ejecución, cantidades, medias... en un archivo y se comunica al Cliente que hemos
acabado.
Se estudiará la evolución del terreno durante 45 años.
31
Para este programa necesitamos algunas variables globales, una estructura de Datos.
5.2,3.1. Variables.java
Esta clase contendrá las variables globales así como las funciones para trabajar con
ellas. Estas funciones serán synchronizable, es decir no pueden acceder a ellas más de un
hilo de ejecución simultáneamente.
//Datos que cogemos del fichero ‘Treball.dat’
riscIncendi
creixVegetacio
capExtincio
incendisAnuals
errorExtincio
//Datos que devolveremos en el fichero ‘Resultat.dat’
incendis ->
nº de incendios registrados
mitjaIncendis
->
media de incendios por año
territoriCremat
->
total de píxeles quemados
mitjaCremat
->
media de píxeles quemados por año
incendisExt
->
incendios extinguidos por los bomberos
incendis10 ->
incendios mayores de 10 píxeles
incendis100
->
incendios mayores de 100 píxeles
incendis1000
->
incendios mayores de 1000 píxeles
//Otras variables
meteorología
->
meteorología de cada año, es un random
grocs
->
total de píxeles secos
verds
->
total de píxeles con vegetación
roigs
->
total de píxeles quemados
intensitat ->
intensidad del incendio
//Estructuras de Datos
territori
->
Es una tabla de enteros que representa el territorio 300 x 270,
cada entero puede tener 3 valores (GROC,VERD,ROIG), según su estado
//Funciones
Todas las funciones que se requieren para poder cambiar el valor, o acceder a cada
una de estas variables están en esta clase. Tambien las funciones para acceder a ‘territori’.
También incluye 4 funciones para inicializar, cargar o guardar las variables.
- iniVariables() : inicializa las variables de ‘Treball.dat’ por defecto
- getVariables() : carga las variables del fichero ‘Treball.dat’.
- iniDades() : inicializa el resto de variables
- guardarDades() : guarda los resultados en el fichero ‘Resultat.dat’.
Funciones, variables y estructura de Datos son estáticas.
Además de estas variables, el programa debido a la cantidad de información que
maneja necesita otra estructura de Datos
5.2.3.2. Cua.java
Esta clase implementa una estructura ‘Cola’. Con sus respectivas funciones de
‘encuar’ y ‘desencuar’. En esta cola iremos introduciendo todos los píxeles que se vayan
incendiando durante la propagación para irlos tratando uno a uno. Lo ideal podría ser
hacerlo con una función interna recursiva que tratase la propagación, pero requiere
demasiado espacio de memoria, y colapsaría la pila.
32
Para poder comunicarse con la interficie Grafica del programa Cliente le pasamos a
este programa una pequeña Interface. Esta comunicación es necesaria, ya que el simulador
de incendios tiene que poder comunicar al Cliente que ha acabado, o bien que se ha
detenido, o que se ha producido un error durante su ejecución...
5.2.3.3. InterficieCalcul.java:
public interface InterficieCalculI {
//Notificar que se ha finalizado el Trabajo, y actualizar //
estado del Programa
public void fiTreball();
//Notificar un Error
public void error();
//Notificar error grave
public void errorGreu();
//Retorna si el programa Cliente está parado o en marcha
public boolean getEstat();
//Notificar que hemos parado el simulador y actualizar el //
estado
public void aturar();
//Notificar que reanudamos el simulador y actualizar el estado
public void continuar();
}
Por último el Simulador tiene que poder mostrarnos cual es el progreso de sus
Cálculos, mostrarnos el aspecto del territorio año tras año, cuales son los datos parciales, y
una gráfica con la evolución del terreno.
El terreno será un panel de 300 x 270 que recorrerá la tabla ‘territori’ para su
repintado. Este panel se añadirá a otro panel que nos proporcionará una función estática
para actualizarlo. Territori.java y PanelTerritori.java
La gráfica será un panel, con ‘años’ minipaneles añadidos. Cada año transcurrido se
calcularan los porcentajes de cada tipo de píxel, y se guardaran en su miniPanel para
posteriores repintados. Este panel se añadirá a otro panel que nos proporcionará una
función estática para actualizar cada miniPanel
Grafic.java y PanelGrafic.java
Los cálculos parciales se mostraran en una serie de etiquetas. Las etiquetas se
añadirán a otro panel que nos proporcionará una función estática para actualizar cada
etiqueta.
PanelEtiqs.java
33
Una vez diseñado todo lo necesario para la visualización y control del Simulador de
incendios procedemos a implementarlo:
5.2.3.4. SimularIncendi.java
Variables:
Cua Cola
InterficieCalcul interficie
Funciones Locales
CalculaPp (pixelsCremats) -> Calcula la probabilidad de que el fuego se propague a
un píxel vecino a partir del riesgo de incendios, la meteorología, la intensidad del
incendio y los píxeles ardiendo a su alrededor. Si se propaga, retorna ROIG, sino,
retorna VERD
CalcularPe -> Compara la capacidad de extinción de los bomberos con la intensidad
del fuego, si la capacidad es mayor, calcula la probabilidad de que se produzca un
fallo humano. Si no es así el fuego se apaga. Retorna true si apagamos el incendio y
false sino.
PropagarIncendi(x,y) -> Le pasamos las coordenadas del píxel desde el que se
propaga el incendio.
Explorar píxeles vecinos incendiados
Por cada vecino
Si vecino tiene vegetación
Si CalcularPp(vecinos incendiados) = ROIG
Encuar(vecino)
Roigs ++
Fsi
Fsi
Fpor
ImplantarVegetacio() -> Recorre toda la tabla ‘territori’ si el píxel está GROC, deja
que haya vegetación según la probabilidad que le pasamos como Dato. Actualiza la
variable ‘verds’
SecarCremats() -> Recorre toda la tabla pasando todos los píxeles ROIG a GROC.
Actualiza la variables ‘grocs’ y la variable ‘roigs’
34
Programa Principal:
IniDades()
GetVariables()
Actualizar las etiquetas
Actualizar grafica
Actualizar territorio
Por numero de años
Si el Programa Cliente esta en marcha
ImplantarVegetacio()
SecarCremats()
Calcular nueva meteorología
Por incendisAnuals
Elegir un píxel
Si píxel es VERD
Calcular la probabilidad de que se incendie
Si se incendia
Crear cola
Encuar (píxel)
Mientras no cola vacía & incendio no apagado
Desencuar (píxel)
PropagarIncendi (píxel)
Fmientras
Fsi
Fsi
Fpor
Actualizar variables
Actualizar etiquetas
Actualizar grafica
Actualizar territorio
Sino
Avisar de que estamos parados al Cliente
Mientras Cliente Parado
Dormir 1 segundo
Fmientras
Avisar de que continuamos con la ejecución al Cliente
Fsi
Fpor
GuardarDades()
Avisar al cliente de que hemos finalizado la ejecución
Control de excepciones
Si Error
Avisar al cliente del Error
Si Error Grave
Avisar al cliente del Error Grave
Fcontrol
35
5.3 DISEÑO DEL SERVIDOR
Para administrar correctamente el programa Servidor, el administrador debe llevar a cabo
una serie de funciones de mantenimiento.
Una de sus misiones principales será mantener en todo momento el la Interface remota
registrada en el Servidor RMI, ya que en el momento que deje de estar registrada, ningún
cliente podría conectarse para hacer peticiones, por tanto debemos proporcionar una
herramienta de control del Registro, a ser posible que no sea manual. Esta herramienta será un
Thread que se ejecutará cada 15 minutos y comprobará que la nuestra Clase esté registrada en
el Servidor RMI, en caso de que no lo esté debe informar inmediatamente al administrador
mediante la interficie Gráfica, con un Diálogo de error, o una frase que destaque dentro de la
interficie. Para ello proporcionaremos al administrador dos funciones:
- Registrarse en el Servidor
- Desregistrarse del Servidor.
La Otra misión que tendrá el administrador como tal es mantener la Base de Datos en
correcto funcionamiento mientras se ejecute el programa. Esto implica que debemos
proporcionar al administrador herramientas gráficas con las que poder gestionar la Base de
Datos y corregir errores en caso de que se produzcan.
Para esta función se proporcionará al administrador una serie de funciones que ayuden a
modificar o comprobar la consistencia de la Base de Datos.
- Añadir un Trabajo
- Añadir un Trabajo desde las copias de Seguridad
- Borrar un Trabajo
- Borrar un Cliente
- Comprobar la consistencia de la Base de Datos
- Renovar la conexión del Programa con la Base de Datos.
- Retornar a Pendiente un trabajo que lleve demasiado tiempo Asignado
Además de estas funciones el administrador tiene que poder echar un vistazo a la Base de
Datos en cualquier momento y de forma clara.
Para todas estas tareas lo más adecuado seria que se pudieran ejecutar desde JDialogs que
el programa generase al llamarlas el administrador. Por otra parte el contenido de la Base de
Datos debe estar en todo momento en pantalla, por ejemplo con un JTabbedPane que nos
permitiera en todo momento consultar tanto los trabajos como los clientes de la Base de Datos
y ordenados según el gusto del administrador.
Para la última función lo mejor sería que se ejecutara sin necesidad de que el
administrador la demandara. Podemos construir un Thread que compruebe que si hay trabajos
de ese tipo, los actualice y en caso necesario informe al administrador. Esta tarea la podríamos
ejecutar una vez al día.
Todas estas funciones deben ser accesibles desde la Ventana principal de la interficie
gráfica, y deben informar inmediatamente al usuario si detectan un fallo tal y como hacemos si
se cae el Registro RMI.
La última misión del Servidor será la de llevar un registro diario de los sucesos que se
generen en nuestro Programa, tales como los registros de usuarios, las actualizaciones de los
distintos trabajos, y cualquier operación que se realice con la base de Datos, debe quedar
registrada para que el administrador pueda consultarlos en un futuro. También podemos dar la
posibilidad al administrador de guardar una copia del estado de cualquiera de las Tablas de la
Base de Datos para su posterior Consulta. Todos estos archivos de historial generados
podríamos guardarlos en un directorio ‘Log’, y dentro de este en un directorio con la fecha en
que se guardaron para facilitar la consulta posterior.
Tampoco estaría de más dejar que el administrador consulte los propios trabajos, ya sean
pendientes, asignados, o los resultados obtenidos de uno de ellos.
36
Por último hay que implementar herramientas gráficas para que el administrador pueda
ejercer esas consultas de historial desde la ventana principal del programa Servidor, y no por
ejemplo desde el explorador de archivos.
Por lo tanto nos encontraríamos con las siguientes funciones:
- Consultar un archivo de Log
- Consultar un Trabajo.
Todos los archivos de los trabajos de la BD tienen que estar guardados en sus directorios
correspondientes para facilitar el acceso de las tareas del Servidor.
Nosotros crearemos 4 directorios en nuestro Servidor:
- Treballs -> Contendrá todos los trabajos no completados, es decir, los
pendientes y los asignados.
- Completats -> Contendrá todos los trabajos completados.
- NoAfegits -> Contendrá los trabajos que no están contenidos todavía en
nuestra BD.
- Backup -> Contendra una copia de todos los trabajos antes de ser completados
para que en caso de que uno se extravíe podamos recuperarlo.
Además de todo esto contaremos al igual que en el Cliente con una serie de Variables
globales y funciones para modificarlas desde las diferentes Clases.
Dades.java
estat -> Estado actual del Servidor RMI
peticions -> Nº de peticiones en curso
petDescarrega -> Peticiones de Descarga en Curso
petTransfer -> Peticiones de Envío en Curso
petRegistre -> Peticiones de Registro en Curso
Además de las funciones para modificarlas o acceder a ellas, todas ellas estáticas.
Una vez visto todo esto procedemos a diseñar las dos partes del Servidor:
1. Base de Datos
2. Interficie Grafica
El diseño de las funciones Remotas ya lo hemos visto en el apartado 5.1
37
5.3.1 DISEÑO DE LA BASE DE DATOS
Para la Base de Datos del Programa sólo son necesarios dos tablas, una para guardar
los Trabajos, y otra para guardar los Clientes.
1. Tabla Treballs:
En esta tabla guardaremos toda la información concerniente a los trabajos que
tenemos. La descripción de la Tabla será:
Campo
NomFitxer
Tipo
Descripción
Clave Primaria, es el nombre del
fichero asociado al trabajo con este
mismo nombre.
Indica la prioridad con que se
descargará el trabajo
Indica si el trabajo está pendiente de
ser asignado (0), asignado (1), o
Completado (2)
Es el login del Cliente al que está
asignado el trabajo, o por el que ha
sido completado
Fecha en que se asignó, o se
completó el trabajo
varchar(20)
Prioritat
varchar(1)
Estat
int
User
varchar(10)
Data
date
2. Tabla Clients
En esta tabla almacenaremos a los clientes que se registren en nuestra Base de
Datos.
Campo
user
Tipo
Descripción
Clave Primaria, es el login del
Cliente.
Es el nombre que del usuario cliente.
nº de trabajos que el cliente ha
completado.
Es la última fecha en que el cliente
hizo una petición de función remota.
varchar(10)
Nom
TrebComp
varchar(40)
int
Data
date
38
Además debemos proporcionar al Programa una serie de funciones que nos permitan
trabajar con estas Tablas. Para ello implementamos la Clase MetodesBD donde
implementaremos estas funciones. Todas estás funciones serán Estáticas y síncronas:
5.3.1.1. MetodesBD.java
IniBD()
Establece la conexión con la base de Datos a través de API de JDBC
com.MySQL.driver.
String agafarTreball()
retorna el nombre del primer trabajo disponible según la prioridad.
int comprobarUser(String user)
retorna 1 si el usuario existe en la Base de Datos, y 0 sino existe
int comprobarAssignacio(String user, String nomTreball)
retorna 1, si el campo user del trabajo que le pasamos por parámetro es igual al
String user que le pasamos, 0 sino.
int guardarUser(String user, String nomClient)
retorna 1 si ha guardado al nuevo usuario y 0 si ya existe un usuario con ese login
int guardarPendent(String nomTreball, String Prioritat)
guarda el nuevo trabajo en la BD con la prioridad indicada. El campo user por
defecto es ‘zzzzzzzzz’ y el campo data es ‘null. El campo estat como es obvio es
‘PENDENT’.
1 si todo bien, 0 si el trabajo ya existe
int guardarAssignat(String user, String nomTreball)
del trabajo indicado actualiza los campos estat ‘ASIGNAT’, user -> user, data ->
captura la fecha de ese día.
También del Cliente user, actualiza el campo data con la fecha de ese día.
1 si todo bien, 0 si el trabajo no existe.
int guardarComplet(String user, String nomTreball)
del trabajo indicado actualiza los campos estat ‘COMPLET’, data -> captura la
fecha de ese día.
1 si todo bien, 0 si el trabajo no existe.
int tornarAPendent(String nomTreball)
actualiza el trabajo a pendiente inicializando los campos user y data, estat ->
PENDENT
1 si todo bien, 0 si no existe el trabajo
int actualitzarUser(String user)
Aumenta los trabajos completados del cliente user y actualiza la fecha de
conexión
1 si todo bien, 0 si no existe el cliente.
int actualitzarPrioritat(String nomTreball, String Prioritat)
cambia la prioridad del trabajo nomTreball.
1 todo bien, 0 el trabajo no existe
39
int decUser(String user)
decrementa en 1 los trabajos completados del Cliente user, ya actualizamos la
fecha.
1 todo bien, 0 el Cliente no existe
int borrarClient(String user)
Elimina de la tabla Clients al Cliente user.
1 todo bien, 0 el cliente no existe
int borrarTreball(String nomTreball)
Elimina de la tabla Treballs el trabajo nomTreball
1 todo bien, 0 el trabajo no existe
String[][] llistarClients(int mode)
Retorna una tabla con los datos de todos los clientes ordenados según mode.
Mode 1 -> login del Cliente
Mode 2 -> nombre del Cliente
Mode 3 -> nº de trabajos completados
Mode 4 -> fecha
String[][] llistarPendents(int mode)
Retorna una tabla con los datos de todos los trabajos donde estat = ‘PENDENT’.
Ordenados según mode.
Mode 1 -> nombre del Trabajo
Mode 2 -> Prioridad del Trabajo
String[][] llistarAssignats(int mode)
Retorna una tabla con los datos de todos los trabajos donde estat = ‘ASSIGNAT’.
Ordenados según mode.
Mode 1 -> nombre del Trabajo
Mode 2 -> login del Cliente
Mode 3 -> fecha de asignación
String[][] llistarCompletats(int mode)
Retorna una tabla con los datos de todos los trabajos donde estat = ‘COMPLET’.
Ordenados según mode.
Mode 1 -> nombre del Trabajo
Mode 2 -> login del Cliente
Mode 3 -> fecha de asignación
String[][] llistarTreballs(int mode)
Retorna una tabla con información de todos los trabajos de la BD. Ordenados según
mode
Mode 1 -> nombre del Trabajo
Mode 2 -> Prioridad del Trabajo
Mode 3 -> login del Cliente
Mode 4 -> fecha de asignación
Mode 5 -> estado del trabajo
int nombreClients()
retorna el nº de Clientes que contiene la Tabla.
int nombrePendents()
retorna el nº de trabajos pendientes que contiene la Tabla
int nombreAssignats()
40
retorna el nº de trabajos asignados que contiene la Tabla
int nombreCompletats()
retorna el nº de trabajos completados que contiene la Tabla
int nombreTreballs()
retorna el nº de trabajos que contiene la Tabla
String[][] TreballsCaducats()
Esta función retorna una tabla con todos los trabajos cuyo campo estat =
‘ASSIGNAT’ y cuya fecha sea menor o igual a la fecha de hace 5 días.
int revisarBD()
Por cada trabajo que se encuentre en la base de datos, comprueba que el fichero
asociado está donde debe estar, si no es así, borra el trabajo, e informa al usuario a
través de un fichero de log.
void recuperarConexio()
Restablece la conexión con la base de Datos a través de API de JDBC
com.MySQL.driver. Esta función debe ejecutarse si en algún momento se cae
MySQL.
void tancarConexio()
Cierra la conexión con el API
Como vemos el control de la Base de Datos requiere muchas más funciones de las que
podríamos pensar debido a la sencillez de la tablas. Todas las funciones generan la
excepción SQLException, que es tratada fuera de esta clase por la Clase que utiliza las
funciones. Si esta excepción fuera generada, el Servidor tiene que informar
inmediatamente al administrador que la conexión que MySQL se ha perdido, o bien que
MySQL no está en funcionamiento, para que el administrador resuelva el problema lo
antes que pueda.
41
5.3.2 DISEÑO DE LA INTERFICIE GRÁFICA DEL SERVIDOR
La interficie gráfica con la que el administrador trabajará será una ventana principal
JFrame desde la cual se podrá acceder rápidamente a todas las funciones que hemos
descrito.
Dividiremos la interficie en tres partes:
5.3.2.1. Barra de Menús:
La Barra de menús como en toda aplicación ocupará la parte superior de la
pantalla y constituirá la herramienta principal para gestionar la Base de Datos,
Registrar o Anular el registro en el Servidor RMI, y consultar los archivos de Trabajo
o de Log.
Puesto que se trata de tres tareas diferenciadas crearemos tres menús:
5.3.2.1.1.
Menú Servidor:
Desde este menú podremos registrar o anular el registro RMI.
Antes de describir estas dos funciones veremos el diseño del Thread descrito
anteriormente que se encarga de comprobar que estamos registrados en el Servidor
cada 15 minutos, ya que esta muy relacionado con estas dos funciones.
ComprovacioRMI.java
Run()
Parar = false
mientras (no parar)
Dormir 15 minutos
Comprobar registro
Control de Excepciones
Si registro no encontrado
Parar = true
Estat = ATURAT
Avisar al administrador de que se ha perdido el Registro y tiene que
volver a Registrarse.
Fcontrol
Fmientras
Destroy()
Parar = true
Ahora si pasamos a describir las dos funciones:
42
Iniciar Servidor RMI
Si estat = ATURAT
Registrar nuestro Servidor en el Servidor RMI
Crear nuevo comprovacioRMI
Iniciar comprovacioRMI
Estat = ENGEGAT
Informar al administrador
Sino
Si estat = ACTUALITZANT
Informar al administrador que en estos momentos el Programa esta
realizando tareas de mantenimiento y no puede registrar al Servidor
Sino
Informar al administrador que nuestro servidor ya esta registrado.
Fsi
Fsi
Control de excepciones
Si no encontramos Servidor RMI
Estat = ATURAT
Informar al administrador que RMI no está en marcha.
Fcontrol
Parar Servidor RMI
Si estat = ENGEGAT
Si no hay peticiones en curso
Anular el registro RMI
Destruir comprovacioRMI
Estat = ATURAT
Sino
Mostrar DialogPeticionsEnCurs
Fsi
Informar al administrador
Sino
Informar al administrador que nuestro servidor ya está anulado.
Fsi
Control de excepciones
Si no encontramos Servidor RMI
Estat = ATURAT
Informar al administrador que RMI no está en marcha.
Fcontrol
Para informar al administrado en estas dos funciones utilizamos un área de
Texto básicamente, un DialogError básicamente iguales a los que utilizamos en el
Programa Cliente y además una Etiqueta que se distingue en la pantalla por se de
Color Rojo y más grande que el Resto (Esta etiqueta solo se muestra en caso de
errores críticos).
DialogPeticionsEnCurs.java
Este Diálogo nos informa de que en estos momentos el Servidor RMI tiene
peticiones remotas que están atendiéndose. Y nos pregunta si queremos parar RMI
igualmente. En caso de que aceptemos, se realiza la misma acción que hemos visto
en la función ‘parar el programa’, con el mismo control de excepciones.
43
5.3.2.1.2.
Menú BD
Este menú nos permite realizar todas las operaciones que hemos mencionado
anteriormente con al Base de Datos. Así pues como ya hemos dicho antes las
funciones de este menú serán:
Añadir Trabajo
DialogAfegir.java
Este diálogo constará de 4 partes:
Tabla de Trabajos:
Campo que nos muestra el nombre del trabajo seleccionado
Combo donde podemos seleccionar la prioridad
Botones -> aceptar, cancelar, backup
Al mostrar este diálogo hacemos lo siguiente:
Si directorio ‘NoAfegits’ existe
Contenido de la Tabla = Contenido del Directorio
Si hay Contenido
Cargar Tabla
Combo = 0
Mostrar Dialogo
Sino
Informar al administrador que no hay trabajos para añadir.
Fsi
Sino
Crear directorio NoAfegits
Aviso Importante
Informar al administrador que se han perdido los trabajos para añadir
Fsi
El botón ‘backup’ nos permite acceder al contenido del Directorio ‘Backup’ que
contiene las copias de seguridad de todos los archivos del Servidor.
Por lo tanto pulsándolo realizamos la misma operación sobre el mismo diálogo
pero mostrando el contenido de este directorio. Desde el que también podemos
añadir cualquier fichero.
Una vez hemos seleccionado el fichero que queremos añadir, ya sea un trabajo no
añadido o una copia de Seguridad, y su prioridad tenemos dos opciones
Aceptar
Ocultar diálogo
Si existe el directorio ‘NoAfegits’ o ‘Backup’ (depende que hagamos)
Si MetodesBD.guardarPendent(trabajo, prioridad) = 1
Actualizar registro de sucesos
Actualizar datos mostrados por pantalla
Si existe directorio ‘Treballs’
Mover fichero de NoAfegits a Treballs ó
Copiar fichero de Backup a Treballs
Sino
Crear directorio Treballs
Actualizar Registro
Avisar de Error Critico
Mostrar DialogError (Perdidos todos los trabajos pendientes y
asignados)
Fsi
44
Sino
Actualizar registro
Error crítico (puede haber inconsistencia en la BD)
Mostrar DialogError(El trabajo ya existe en la BD)
Fsi
Sino
Crear directorio que pertoque
Actualizar registro
Avisar Error Critico
Mostrar DialogError (Perdidos trabajos no añadidos, o copias de seguridad)
Fsi
Control de excepciones
Si ExcepciónSQL
Actualizar registro
Avisar error crítico
Mostrar DialogError(SQL no esta en marcha o perdida la conexión)
Si Excepcion
Actualizar registro
Avisar error crítico
Mostrar DialogError(Error al añadir trabajo)
Fcontrol
Cancelar
Ocultar diálogo.
45
Borrar Trabajo
DialogBorrar.java
Este diálogo tendrá 4 partes
Tabla de Trabajos
Campo de texto que nos muestra el trabajo elegido
Opción de borrar también el fichero asociado
Botones -> borrar, cancelar
Mostrar:
Si existen los directorios ‘Treballs’ y ‘Completats’
Contenido Tabla = MetodesBD.llistarTreballs(1)
Opción no seleccionada
Sino
Crear directorio Treballs o Completats o ambos
Actualizar registro
Aviso error crítico
Mostrar DialogError (Perdida de trabajos)
Fsi
Control de excepciones
Si ExcepciónSQL
Actualizar registro
Avisar error crítico
Mostrar DialogError(SQL no esta en marcha o perdida la conexión)
Fcontrol
Borrar
Ocultar dialogo
Si MetodesBD.borrarTreball(trabajo) = 1
Si existe el fichero asociado
Si opción está marcada
Borrar Fichero
Actualizar registro
Sino
Si estat = pendent o assignat Mover fichero de Treballs a NoAfegits
Actualizar registro
Fsi
Sino
Mostrar DialogError(perdido fichero de trabajo)
Fsi
Sino
Actualizar registro
Mostrar DialogError(el trabajo ya existe)
Fsi
Control de excepciones
Si ExcepciónSQL
Actualizar registro
Avisar error crítico
Mostrar DialogError(SQL no esta en marcha o perdida la conexión)
Si Excepcion
Actualizar registro
Avisar error crítico
Mostrar DialogError(Error al borrar trabajo)
Fcontrol
46
Borrar Cliente
DialogBorrarClient.java
Consta de tres partes
Tabla de Clientes
Campo de texto
Botones -> aceptar y cancelar
Mostrar
Si hay clientes
Contenido tabla = MetodesBD.llistarClients(1)
Sino
Actualizar registro
Mostrar DialogError (tabla clientes vacía)
Fsi
Control de excepciones
Si ExcepciónSQL
Actualizar registro
Avisar error crítico
Mostrar DialogError(SQL no está en marcha o perdida la conexión)
Fcontrol
Aceptar
Ocultar Diálogo
Si MetodesBD.borrarClient (selección) = 1
Actualizar registro
Sino
Actualizar registro
Mostrar DialogError (Cliente no existe)
Fsi
Control de excepciones
Si ExcepciónSQL
Actualizar registro
Avisar error crítico
Mostrar DialogError(SQL no está en marcha o perdida la conexión)
Si Excepción
Actualizar registro
Avisar error crítico
Mostrar DialogError(Error al borrar cliente)
Fcontrol
47
Cambiar la prioridad de un Trabajo
DialogCanviPrioritat.java
Las partes de este diálogo son idénticas a las del DialogAfegir, pero sin el botón
de Backup. Sólo podemos cambiar la prioridad de un trabajo pendiente.
Mostrar
Si existe el directorio ‘Treballs’
Contenido Tabla = MetodesBD.llistarPendents(1)
Prioridad = leer prioridad de la tabla
Sino
Crear directorio
Actualizar registro
Aviso error crítico
Mostrar DialogError (Perdidos trabajos pendientes y asignados)
Fsi
Control de excepciones
Si ExcepciónSQL
Actualizar registro
Avisar error crítico
Mostrar DialogError(SQL no está en marcha o perdida la conexión)
Si Excepción
Actualizar registro
Avisar error crítico
Mostrar DialogError(Error al cambiar prioridad)
Fcontrol
Aceptar
Ocultar diálogo
Si MetodesBD.canviarPrioritat(trabajo,prioridad) = 1
Actualizar registro
Sino
Error crítico (puede haber inconsistencia en la BD)
Mostrar DialogError (El trabajo no existe)
Fsi
Control de excepciones
Si ExcepciónSQL
Actualizar registro
Avisar error crítico
Mostrar DialogError(SQL no está en marcha o perdida la conexión)
Si Excepción
Actualizar registro
Avisar error crítico
Mostrar DialogError(Error al cambiar prioridad)
Fcontrol
48
Revisar la Base de Datos
Esta función no necesita Diálogo ya que es un proceso de recorrido de la tabla
Treballs de la BD. Mejor la construiremos como un Thread, para que su ejecución
sea más dinámica conjuntamente con la interficie gráfica.
RevisarBD.java
Run()
Result = MetodesBD.revisarBD()
Si result = 1
Actualizar registro, no hay ninguna incosistencia
Sino
Actualizar registro
Mostrar DialogError (Se han detectado inconsistencias en la BD, consulta el
fichero de hoy ‘revisioBD’)
Fsi
Control de excepciones
Si ExcepciónSQL
Actualizar registro
Avisar error crítico
Mostrar DialogError(SQL no está en marcha o perdida la conexión)
Si Excepción
Actualizar registro
Avisar error crítico
Mostrar DialogError(Error al revisar la BD)
Fcontrol
Recuperar la Conexión
Esta función tampoco necesita Dialogo ya que es muy rápida y sencilla
Únicamente ejecuta la función MetodesBD.recuperarConexio() haciendo un
control de excepciones como los vistos hasta ahora.
Ya fuera del menú BD pero directamente relacionado encontramos también una tarea
que trabaja con la BD. Esta tarea se encargará una vez al día de repasar los trabajos
asignados que tenemos en nuestra BD y aquellos que lleven más de 5 días asignados, se
modificará su estado a Pendiente. Es una forma de asegurarnos que ningún trabajo se
quedará sin realizar a causa de que un cliente decida darse de baja.
Será un Thread que se ejecute cada hora, si estamos entre las 11 y las 12 de la noche
se ejecuta, sino, vuelve a dormir.
Aprovechando que se ejecutar 1 vez al día, guardaremos una copia del registro, y lo
inicializaremos.
49
ComprovacioCaducitat.java
Mientras true
Si hora actual entre 23 y 24
Guardar Registro
Inicializar Registro
Actualizar Registro
Si estat = ENGEGAT
CompRMI.destroy()
Anular registro RMI
Fsi
Estat = ACTUALITZANT
Contenido = MetodesBD.TreballsCaducats
Si contenido no es nulo
Por cada trabajo
MetodesBD.tornarAPendent()
Actualizar Registro
Anotar en el fichero renovacióBD.log todos los cambios que se efectúen
Actualizar Registro
Sino
Anotar en el fichero que no hay cambios en la BD
Actualizar Registro
Fsi
Actualizar Registro (hemos acabado)
Si hemos parado el Servidor RMI
Registrarnos en el Servidor
Iniciar ComprovacioRMI
Estat = ENGEGAT
Sino
Estat = ATURAT
Fsi
Control de excepciones
Si no encontramos Servidor RMI
Estat = ATURAT
Actualizar registro
Avisar error crítico
Mostrar DialogError(RMI parado)
Si ExcepciónSQL
Actualizar registro
Avisar error crítico
Mostrar DialogError(SQL no está en marcha o perdida la conexión)
Si Excepción
Actualizar registro
Avisar error crítico
Mostrar DialogError(Error al renovar la BD)
Fcontrol
Sino
Dormir 1 hora
Fsi
FMientras
50
5.3.2.1.3.
Menú Consulta
Por último este menú es el que nos permite consultar los datos referentes al
historial de nuestro programa y también el contenido de los trabajos que tenemos
almacenados en nuestra base de Datos.
Las acciones que podremos realizar desde este menú serán las siguientes:
Consultar un archivo de ‘Log’
Para hacer más accesible al administrados esta función la realizaremos como todas
las anteriores mediante Diálogos.
Por lo visto hasta ahora nos podemos encontrar con los siguientes tipos de
archivos log:
- Archivos de contenido de Base de Datos
• Trabajos
• Trabajos pendientes
• Trabajos asignados
• Trabajos completados
• Clientes
- Archivos de sucesos
• Registro de sucesos
• Registro de errores críticos
• Revisión de la Base de Datos
• Registro de trabajos actualizados por estar caducados
DialogConsulta.java
Este Diálogo nos permitirá acceder a un pequeño explorador de archivos de
fabricación propia que consiste en una tabla que nos muestra el contenido del
Directorio ‘Log’, después nos permite abrir sus directorios y mostrar su contenido,
o bien volver atrás al directorio ‘Log’. Una vez seleccionado el archivo a mostrar,
cerraremos este dialogo y abriremos otro con el contenido del fichero.
Así pues este dialogo tendrá tres partes
- Tabla -> Explorador de archivos
- Campo con la selección
- Botones -> Subir un nivel, abrir, cancelar
Mostrar
Si existe directorio ‘Log’
Contenido de Tabla = contenido del Directorio
Sino
Crear directorio
Actualizar registro
Aviso error crítico
Mostrar DialogError (Perdido historial)
Fsi
Subir un nivel
Si no estamos en el directorio ‘Log’
Si existe directorio ‘Log’
Contenido de Tabla = contenido del Directorio
Sino
Crear directorio
Actualizar registro
Aviso error crítico
Mostrar DialogError (Perdido historial)
Fsi
Fsi
51
Abrir
Si estamos en directorio ‘Log’
Si directorio seleccionado es correcto y existe
Contenido Tabla = contenido directorio seleccionado
Sino
Volver a Directorio ‘Log’
Fsi
Sino
Ocultar Dialogo
Mostrar DialogVeureArxiu (fichero seleccionado)
Fsi
Control de excepciones
Si Fichero no existe
Actualizar registro
Avisar error crítico
Mostrar DialogError(Fichero de Log perdido)
Si Fichero alterado
Actualizar registro
Avisar error crítico
Mostrar DialogError(Fichero de Log alterado)
Si otra excepción
Actualizar registro
Avisar error crítico
Mostrar DialogError(Error al mostrar fichero)
Fcontrol
DialogVeureArxiu.java
Este Diálogo tiene dos modalidades. Según tenga que mostrar un fichero de
contenido de BD, o uno de texto.
Para los archivos de BD, el diálogo se presenta con una Tabla que muestra el
contenido, y un botón para cerrar el diálogo.
Para los archivos de texto el modelo es el mismo, pero en lugar de una tabla
los datos se presentan en un área de Texto.
52
Consultar un Trabajo
En el menú de consulta dejaremos que el administrador decida que tipo de trabajo
quiere consultar. El Diálogo que mostraremos en cada caso será el mismo, pero con
distinto parámetro, según el Dialogo.
DialogResultats.java
Tendrá tres partes:
- Una tabla en la que se muestran los archivos que podemos ver
- Campo de selección
- Botones -> aceptar, cancelar
Mostrar
Si directorios Treballs y Completats existen
Si mostramos trabajos completados
Contenido Tabla = Trabajos Completados
Si mostramos trabajos asignados
Contenido Tabla = Trabajos asignados
Si mostramos trabajos pendientes
Contenido Tabla = Trabajos pendientes
Sino
Crear directorio
Actualizar registro
Aviso error crítico
Mostrar DialogError (Perdidos trabajos)
Fsi
Control de excepciones
Si ExcepciónSQL
Actualizar registro
Avisar error crítico
Mostrar DialogError(SQL no está en marcha o perdida la conexión)
Fcontrol
Aceptar
Ocultar Dialogo
Mostrar DialogVeureTreball
Control de excepciones
Si Fichero no existe
Actualizar registro
Avisar error crítico
Mostrar DialogError(Fichero de Log perdido)
Si Fichero alterado
Actualizar registro
Avisar error crítico
Mostrar DialogError(Fichero de Log alterado)
Si otra excepción
Actualizar registro
Avisar error crítico
Mostrar DialogError(Error al mostrar fichero)
Fcontrol
DialogVeureTreball.java
Es básicamente igual que el DialogVeureArxiu, pero solo necesita un área de texto
para mostrar ficheros, ya que no necesita mostrar contenido de BD.
53
5.3.2.2. Zona de Control del Estado del Servidor.
Esta zona ocupara el la mitad superior de la ventana principal de la Aplicación.
Constará de dos partes o paneles:
-
En el panel izquierdo mostraremos todos los datos que maneja el programa
mediante etiquetas que serán los siguientes:
Estado del Servidor
Peticiones en Curso
Peticiones de Descarga
Peticiones de Envío
Peticiones de Registro
Clientes Registrados
Trabajos en la BD
Trabajos Pendientes
Trabajos Asignados a Clientes
Trabajos Completados
Alarma
Esta última etiqueta se pone en rojo cuando se produce un error considerado como
crítico para el funcionamiento de la Base de Datos. El administrador debe reaccionar
rápidamente y arreglarlo.
PanelDaltEsq.java
Además de estas etiquetas el panel proporciona una función para cambiar su
contenido indicando el número de la etiqueta que queremos cambiar, no podemos
cambiarla directamente. Cada vez que desde alguna de las clases se cambie el valor de
alguno de estos campos, se procederá a actualizar su etiqueta correspondiente.
En el panel Derecho mostraremos un área de texto donde irán apareciendo todos
los sucesos que ocurren durante la ejecución. Dicha área de texto no es editable.
PanelDaltDret.java
Además del Área de texto, para escribir dichos mensajes, este panel nos
proporciona la función ‘afegirText(text)’ que nos permite escribir en el área de texto
desde cualquier clase. En los pseudocódigos vistos hasta ahora se ha puesto como
“Actualizar Registro”, o Informar al Administrador. Cada vez que se produzca un
evento, ya sea un error, una petición, una operación en la BD, aparecerá reflejada en
este registro.
Además de esta función este panel también nos proporciona la función
‘guardarRegistre()’ que guarda el contenido del registro en el archivo
‘/Log/fecha/incidencies.txt’ para una posterior consulta del administrador. Esta
función además de ejecutarse cada vez que se cierra el programa. Se Ejecuta cada día
al menos una vez mediante el Thread ComCaducita.java, que veremos más adelante.
También permite inicializar el área de texto mediante la función ‘iniRegistre()’.
54
5.3.2.3. Zona de Control de la Base de Datos.
Esta zona ocupa el resto de la ventana, es decir, la mitad inferior. Desde esta zona,
podemos consultar en un momento el contenido de cualquiera de las Tablas de que
disponemos en nuestra Base de Datos, ordenarla a nuestro gusto para encontrar antes
lo que buscamos, y realizar copias del contenido actual de las Bases de Datos.
Esta zona esta compuesta de un JTabbedPane en el que colocaremos hasta 6
paneles en los que añadiremos la información descrita en el párrafo anterior. Esta
clase será Selector.java. Y los 6 paneles que contendrá serán los siguientes:
-
PanePanel1 -> Todos los Trabajos
PanePanel2 -> Trabajos Pendientes
PanePanel3 -> Trabajos Asignados
PanePanel4 -> Trabajos Completados
PanePanel5 -> Clientes Registrados
PanePanel6 -> Éste se sale un poco de la dinámica de esta zona, ya que nos
muestra los avisos considerados como Error Crítico
Procederemos ahora a describir los paneles.
PanePanel1.java
El panel contiene la siguiente información
- Tabla con el contendido de la Tabla Treballs que ocupa la mayor parte del panel.
Esta tabla no es editable ni da acceso a ninguna función de la Base de Datos, es
simplemente una herramienta de Consulta, o Control del contenido de la Tabla.
- Opciones de ordenación de la Tabla. En la parte derecha superior del panel.
El panel te permite ordenar la tabla según distintos campos. En este caso:
• Nombre del Trabajo
• Prioridad
• Login del Cliente
• Fecha de asignación / finalización
• Estado del Trabajo
- Botón Guardar en la parte derecha inferior. Este botón muestra el dialogo
DialogGuardarFitxer, que se encarga de guardar toda la información de la tabla en
el Fichero /Log/fecha/Treballs.txt. Para su posterior Consulta.
El Constructor del panel, carga la tabla con la función MetodesBD.llistarTreballs(1)
que ordena la tabla según el nombre.
Cada vez que cambiamos el orden con que queremos visualizar la tabla, se genera
un evento que tratamos en el panel actualizando la Tabla. Esto se hace llamando de
nuevo a la función MetodesBD.llistarTreballs(opción). El resultado de la función se
carga en la Tabla.
El Panel también nos proporciona una función para que podamos actualizar la Tabla
desde las demás Clases. La función ActualizarPane1() la usan el resto de clases cada
vez que realizan una operación en la BD. Así nos aseguramos que los datos
mostrados por la tabla son en tiempo real.
Por último, el botón Guardar nos muestra el Diálog DialogGuardarFitxer, que es un
diálogo por simple cuestión estética, ya que no permite hacer nada, simplemente
muestra un pequeño diálogo vacío con el título “Guardando Datos”
Si el Panel al cargar una de las Tablas detecta un Error SQL, informa
inmediatamente al administrador de que SQL no funciona o se ha perdido la
conexión, y muestra la ‘Alarma’.
55
La implementación de los 5 primeros paneles es muy parecida, y sólo varia el
numero de columnas de la Tabla, y las opciones de ordenación disponibles. Por
supuesto también varia la función de MetodesBD que utilizamos para llenar el
Contenido de la Tabla en cada panel, pero eso resulta obvio. El resto de
Características son las mismas.
PanePanel2.java
-
Modos de ordenación
• Nombre del Trabajo
• Prioridad
Fichero que guarda -> TreballsPendents.txt
Función de la BD que utiliza -> MetodesBD.llistarPendents(mode)
PanePanel3.java
-
-
Modos de ordenación
• Nombre del Trabajo
• Login del Cliente
• Fecha de Asignación
Fichero que guarda -> TreballsAssignats.txt
Función de la BD que utiliza -> MetodesBD.llistarAssignats(mode)
PanePanel4.java
-
-
Modos de ordenación
• Nombre del Trabajo
• Login del Cliente
• Fecha de Asignación
Fichero que guarda -> TreballsCompletats.txt
Función de la BD que utiliza -> MetodesBD.llistarCompletats(mode)
PanePanel5.java
-
-
Modos de ordenación
• Login del Cliente
• Nombre del Cliente
• Trabajos Completados
• Fecha última conexión
Fichero que guarda -> Clients.txt
Función de la BD que utiliza -> MetodesBD.llistarClients(mode)
PanePanel6.java
Como ya hemos dicho este panel es distinto al resto, tiene el título de “Avisos
Importantes”. Es básicamente un registro igual que el de la Zona de Control del
Servidor, pero sólo muestra los mensajes que se deben a errores críticos en el
Servidor.
Además ofrece la posibilidad de Guardar los datos en un Fichero, y también de Borrar
el contenido del Registro.
Sus componentes son pues:
- Área de texto donde se escriben los errores
- Dos botones -> borrar y guardar.
Cuando mostramos este panel, se ‘apaga la alarma de avisos críticos, ya que se
entiende que el administrador los ha visto.
56
La interficie gráfica de la aplicación carga al ejecutarse estas tres zonas para que el
administrador pueda en todo momento disponer de ellas.
Además de todo esto, la interficie necesita de algunos diálogos más para su correcta
comunicación con el administrador:
DialogError.java
Es el mismo para todas las clases, se pasa por parámetro a todos los constructores, así
nos aseguramos que tenemos siempre controlada su visibilidad.
Cuando ejecutamos la opción de salir del programa pueden darse 2 supuestos.
• Que el Servidor RMI este registrado.
El Programa informa al administrador que no puede cerrar el Programa sin antes
anular el registro en el Servidor RMI mediante un DialogError.
• Ninguna de las dos anteriores.
El Programa nos muestra un DialogFinal que es básicamente igual que el del
Programa Cliente.
DialogFinal.java
Si elegimos la opción ‘SI’ el DialogFinal se oculta, el Frame principal también se
oculta, y la interficie gráfica nos muestra un pequeño diálogo mientras guarda todos los
datos del Programa.
DialogTancament.java
Lo único que hace es guardar una copia del Registro en los archivos de ‘Log’
Por último necesitamos unos Frames especiales que se desplieguen en caso de que al
Cargar el programa Cliente nos encontremos con Errores críticos que no nos permitan su
correcto funcionamiento. Todos ellos una vez cerrados, salen del programa:
Estos son
DialogNoInici.java
Nos comunica que ya existe una aplicación Servidor en funcionamiento y por lo tanto
no se puede ejecutar una copia.
DialogNoSQL.java
MySQL no está en funcionamiento, por lo tanto es imposible cargar la BD, con lo que
no se puede ejecutar el Servidor. Necesitamos poner en marcha SQL.
Unos últimos apuntes sobre la interficie gráfica.
- Todos los Diálogos gracias a Swing se pueden controlar mediante el Teclado, sin
necesidad del Ratón
- Todos los Diálogos son modales, es decir mientras estén visibles la Ventana principal
esta inactiva
57
6. CONCLUSIONES
En líneas generales se han cumplido todas las expectativas que me había marcado al
iniciar este proyecto.
El Programa Servidor de Trabajos proporciona todas las herramientas necesarias para
llevar a cabo una correcta gestión y actualización de una considerable cantidad de
información, ya que la Base de Datos actual almacena unos 7000 trabajos. Además el hecho
de almacenar en la Base de Datos únicamente la información que necesita el Servidor, dejando
en los fichero la información propia del trabajo, dota al Servidor de una considerable
independencia del tipo de estudio que realicemos.
En caso de funcionamiento óptimo, el administrador no tiene que preocuparse de nada, ya
que el Servidor por si sólo es capaz de registrar clientes, enviar y recibir trabajos, y actualizar
toda la información, y llevar a cabo una política de actualización de trabajos que corren el
peligro de no ser completados. Por otra parte es un programa muy robusto capaz de detectar
todos los errores que se pueden producir, corregirlos en su caso, y avisar inmediatamente al
administrador en caso de que se le necesite para resolver el problema.
Podría haberse mejorado el Servidor haciendo que la Base de Datos fuese mucho más
estricta, por ejemplo impidiendo repeticiones de Nombre de los clientes, o impidiendo que un
cliente pudiera tener más de dos trabajos asignados, y en caso de que se fuera a dar ese caso,
el servidor reaccionar reenviándole el trabajo que tenía anteriormente, etc...
El Programa Cliente por su parte cumple de sobras su función distributiva, y puede
realizar su función sin que el usuario tenga que estar pendiente de su trabajo, únicamente se le
pide que lo encienda, y que lo pare. También es capaz de detectar los errores de conexión con
el Servidor y parar el programa en caso de no obtener respuesta.
Por otra parte, tanto el Cliente como el Servidor, son casi completamente independientes
del tipo de estudio que queramos realizar. Quizá la única pega que podríamos encontrar en
este sentido es el hecho de que las funciones de mostrar los trabajos son especificas para este
‘estudio’, se podrían haber puesto en un paquete independiente para que pudiésemos cambiar
el tipo de Trabajo con sólo cambiar este paquete. El resto de operaciones tanto del Servidor,
como del Cliente son válidas para cualquier tipo de trabajo, siempre que este trabaje con
ficheros, y no necesite mostrar más información de que muestra este.
En cuanto a la utilización de RMI para la comunicación entre Servidor y Cliente ha sido
una elección acertada, ya que nos proporciona una manera de pasarnos información entre
ambos, con la facilidad que supone llamar a un simple método, sin la necesidad de que el
programador tenga que usar funciones específicas de red. La función de Registrar usuario por
ejemplo se realiza íntegramente con parámetros de entrada y de Salida. Para las funciones de
transferencia y Dado el tipo de trabajo que realizamos, podríamos decir que desaprovechamos
la funcionalidad de RMI al utilizar sockets para la transferencia de ficheros, podríamos haber
enviado o devuelto la información a través de Strings que fueran luego tratados en la máquina
de destino. Pero de esta forma perderíamos la independencia del Trabajo de que hemos
hablado anteriormente ya que con un trabajo de tratamiento de imágenes por ejemplo, no
podríamos retornar el resultado mediante un parámetro serializable, ni enviar los de entrada
tampoco.
La interfaz gráfica tanto del usuario como del cliente es muy completa, y permite al
Servidor tener acceso a todo el contenido de la Base de Datos rápidamente, así como a todas
las funciones, mientras que el cliente puede entretenerse simplemente mirando el progreso del
simulador.
También puede considerarse un tremendo acierto el uso de Swing para el diseño de la
interfaz gráfica. Al inicio del proyecto la diseñé con AWT, lo cual ofrecía un aspecto mucho
más precario, y el modelo de delegación de eventos era más rudimentario. Swing aparte de ser
compatible con cualquier plataforma da una apariencia mucho más agradable a la interfaz.
58
Todo y no ser una de las partes más importantes del proyecto, el programa de Cálculo
intensivo a realizar resultó una de las tareas más complicadas del proyecto, no por la
complejidad que requiere, sino por elegir el apropiado. Tras muchos intentos con
procesamiento de video o imágenes, me decidí por este simulador de incendios a partir de una
pagina de la facultad de ciencias medioambientales de la UAB, ya que podía construir uno
propio a partir de las instrucciones de su funcionamiento, sin necesidad de estudiar ninguna
librería de java acerca del procesamiento de video por ejemplo. Al final ha sido una elección
acertada ya que en determinados momentos de ejecución alcanza el 100% de utilización de la
CPU, y se ha hecho de manera que el programa en si sea semiindependiente de la interfaz del
Cliente y del programa principal, necesitando sólo una serie de funciones para comunicarse
con el estado actual de este, comunicar su propio estado al cliente, e implementar una
visualización gráfica acorde con las condiciones del cliente.
Como posible mejora estaría el hecho de poder accionar su funcionamiento mediante un
salvapantallas tal y como hace el programa SETI@home, lo que haría completamente
innecesaria la función de un usuario salvo que este lo deseara.
Otro pequeño problema que presenta la aplicación, es que la comunicación entre distintas
máquinas es un poco lenta, pero la investigación de estos problemas de la red no formaba
parte de los objetivos que me había marcado.
Resumiendo creo que la Aplicación es capaz de gestionar y realizar de manera bastante
eficiente cualquier problema que necesite de computación distribuida para llevar a cabo su
estudio.
59
7.- BIBLIOGRAFIA
Tanto para el Desarrollo de la Aplicación Servidor Cliente como para la elaboración de
este informe me he basado en la información que he sacado de las siguientes URLs:
http://java.sun.com
http://www.programacion.com/java/tutorial
http://www.programacion.com/java/tutorial/rmi
http://www.itapizaco.edu.mx/paginas/JavaTut
http://www.eclipse.org
http://www.mysql.com
http://www.gridcomputin.com
http://boinc.berkeley.edu/
http://setiathome.berkeley.edu/sah_bout.php
http://jsmooth.sourceforge.net/index.php
Además de otras muchas páginas que he consultado a lo largo de la elaboración del
proyecto sobretodo tutoriales y foros de los cuales no recuerdo el nombre.
60
ANEXO A : MANUAL DEL CLIENTE
A.1. Instalación y Requisitos
Al no genera código ejecutable, un programa Java necesita de una maquina virtual java
para ejecutarse, o lo que es lo mismo un entorno (run-time).
Por lo tanto para que el Cliente funcione, lo único que necesitamos es que nuestro
ordenador posea dicho entorno. Tenemos que instalar JRE (Java Runtime Enviroment) si
nuestro ordenador no lo posee.
También al ser un programa que realiza llamadas a funciones remotas, necesitamos el API
de Java que nos permite realizarlas. Podemos coger la librería de java generation.jar.
Por último también necesitamos las clases de la interfaz remota que el servidor nos
proporciona a través del archivo server.jar que contiene las clases donde el cliente encontrará
las funciones remotas.
Para la instalación y ejecución del programa en si podemos optar por dos opciones:
1. Ejecutar el programa con la maquina virtual Java
Para esto necesitamos tener en el mismo directorio todos los paquetes que va a utilizar
nuestro programa.
Así pues pondremos en el mismo directorio los paquetes calculIntesiu, client,
interfaceRMI, il(generation.jar). este último es el fichero generation.jar descomprimido.
Seguidamente ejecutamos la instrucción
java -Djava.security.policy=java.policy client.ProgramaClient
y pondremos en marcha el programa.
java.policy es un archivo que contiene los permisos que otorgamos al programa. Es el
siguiente:
grant {
permission java.net.SocketPermission "*:1000-65535" , "connect,accept";
permission java.io.FilePermission "C:\\-" , "read,write,delete";
};
2. Generar un fichero ejecutable
Existen aplicaciones que generan archivos .exe a partir de Bytecodes Java. Uno de
estos programas es Jsmooth, que a partir de un fichero .jar construye un ejecutable.
Una vez generado el ejecutable, lo ponemos en el mismo directorio donde tengamos el
paquete il, interfaceRMI (estos dos paquetes siguen necesitándose aparte), el fichero
java.policy, y el fichero server (donde escribimos el servidor por defecto). Y ya podemos
ejecutarlo. De esta forma perdemos una de las principales características de java, que es su
independencia de la plataforma en que la ejecutemos, pero es más cómodo para el usuario
de windows.
Nota : El fichero ‘server’ lo necesitaremos en ambos casos.
61
A.2. Bienvenido al Programa.
La Primera vez que ejecutemos el
Programa esta será la imagen que nos
encontraremos en la pantalla.
Este es el Diálogo de presentación del
programa. Como vemos consta de un
cuadro en el que se nos da la Bienvenida
como nuevos clientes de este grupo de
Trabajo, y se nos pide un login y un
nombre para poder registrarnos.
La parte de abajo nos mostrará el
resultado de la operación de registro
según la efectuemos correctamente o no, y
según la disponibilidad o no del Servidor.
Estos pueden ser los posibles errores
que nos podemos encontrar, y las distintas
reacciones que tendrá el programa:
1. Intentar comenzar sin estar registrados.
2. Intentar registrarnos sin rellenar los campos:
3. Que no Tengamos conexión a internet
62
4. Que el Servidor no esté Disponible en ese momento.
5. Que nuestro login ya este en uso en la BD del
Servidor
Los Errores 2 y 4 también nos los podemos encontrar cuando cargamos el programa, por
ese motivo si esto pasa, el display ya nos muestra el error antes de hacer nada. Para que no nos
molestemos en intentar hacer el Registro.
A.3. Registro Completado
Si Todo va bien y el Servidor está disponible, nuestra conexión a internet funciona
correctamente, rellenamos los campos, y nuestro login no está repetido, nos aparecerá el
siguiente mensaje, y ya podremos empezar la ejecución del programa Cliente.
63
A.4. Primera Ejecución:
Al elegir la opción de empezar el programa nos encontramos con la ventana principal del
Programa Cliente. Este es su aspecto en nuestra primera ejecución:
Observemos los componentes del Programa uno a uno:
En la parte superior izquierda nos
aparece este cuadro que nos muestra cual
el es estado actual del programa así como
también los datos del Cliente. Login,
Nombre, Trabajos completados, Trabajo
actual en proceso, tiempo de CPU, y de
transferencia.
64
En la parte superior central nos encontramos con
este pequeño recuadro que permite al usuario
controlar el programa.
Si miramos ahora a la parte
superior derecha, observamos el
registro de sucesos, en esta
parte irá apareciendo conforme
se produzca información de qué
es lo que está haciendo el
Programa
en
cualquier
momento.
Por último la parte inferior de la pantalla está reservada al Simulador de Incendios. Esta
zona nos muestra información sobre cual es el estado actual de la Simulación. Como vemos es
bastante llamativa, para que capte rápidamente la atención del usuario.
65
A.5. Configuración del Programa:
Aunque pocos, el programa cliente nos permite
configurar una serie de parámetros para nuestra
comodidad. Así pues pulsando el botón de
configuración nos aparece el siguiente diálogo:
Con este diálogo podemos hacer dos cosas, cambiar el servidor al que nos conectamos,
cosa no muy recomendable, ya que podemos elegir un servidor no válido, de ahí el botón que
nos permite recuperar el Servidor
por defecto.
La otra opción configurable es el
modo de ejecución del programa:
Hay dos opciones. La opción
uno para el programa cada vez que
necesitemos realizar una conexión
con la base de datos, esta opción se
incluye para equipos con una
conexión a internet por horas, o
algún otro tipo de impedimento, o
simplemente porque el usuario lo
desee así.
La opción 2 es el modo ideal de
trabajo de este programa. Consiste
en ponerlo en marcha y olvidarse
completamente de él. El programa
continuará con haciendo su función
hasta que el usuario decida pararlo.
Una
vez
que
hayamos
configurado
estas
opciones
aceptamos y podemos ‘Continuar’
con
el
programa
eso
si,
manualmente, es decir utilizando la opción de Control del programa que tiene ese título.
Si cancelamos la operación, ninguno de los cambios realizados tendrá efecto.
La configuración del programa sólo puede realizarse con el programa completamente
parado. Por ello antes de ejecutar la opción configuración debemos darle a la opción ‘Parar’ en
caso contrario, el programa no nos dejará y nos lo advertirá generando un aviso de error.
66
A.6. Ejecución del Programa:
Como ya hemos visto en el Apartado anterior, la ejecución del programa está
condicionada a la configuración del programa. El modo en que estemos influye en el programa
del siguiente modo.
Si estamos en el modo 1, es decir, requerimos que la aplicación nos pida autorización
antes de realizar cualquier contacto con el Servidor, el Programa cada vez que tenga que
efectuar una transferencia, parará el Programa y mostrará el Siguiente mensaje:
Este mensaje, que continuara
en la pantalla hasta que el usuario
reaccione, pide la autorización para
conectarse
con
el
servidor.
También nos ofrece la posibilidad
de parar el programa, y recuerda al
usuario la posibilidad de cambiar el
modo de funcionamiento. Si todo
está en orden elegiremos la opción
de conectar.
Si todo va bien, y la conexión y el Servidor están disponibles pasamos a Descargarnos un
fichero de Trabajo.
El Cliente realiza su petición al Servidor, el Servidor la recibe y nos envía un fichero, si la
descarga es correcta nos encontramos con la siguiente situación:
Podemos ver que el registro de sucesos ha cambiado y en el aparecen los pasos que el
programa ha realizado (Parte derecha). Por otro lado también vemos que la parte izquierda
también nos muestra datos distintos. Así, una vez descargado el fichero, el programa está listo
para procesar. Y en la etiqueta de Trabajo actual en proceso nos aparece el nombre del trabajo
que estamos simulando.
67
El siguiente paso que da el programa es el de ejecutar el Simulador de incendios sin pedir
autorización ni demorarse en ninguna otra cosa:
Así pues podemos observar que la parte inferior de la pantalla nos muestra el progreso de
la simulación:
Podemos ver como en el registro de sucesos nos indican que hemos iniciado el proceso de
Cálculo, mientras en la parte izquierda vemos que nuestro estado actual es Procesando, y el
tiempo de CPU va aumentando conforme avanza la simulación.
Como el usuario puede comprobar la visualización del proceso de simulación es bastante
llamativa e interesante de observar, este proceso es innecesario, ya que el Servidor sólo
necesita los Datos que aparecen en la parte inferior derecha, pero se ha optado por esta
presentación ya que hace que el usuario la encuentre más atractiva, y da una motivación más
para ejecutar el programa, que no únicamente la de mantener al ordenador ocupado.
Si todo va bien y no decidimos detenerlo, el simulador continua con el proceso hasta que
termina con los 45 años de simulación.
68
Una vez que el simulador ha terminado, nos encontramos con esta pantalla:
Vemos que de nuevo el registro de Sucesos nos advierte de un evento, la finalización del
Simulador, mientras que el estado actual del cliente ahora ha pasado a preparado para
Transferir. También vemos todo el tiempo que el simulador ha consumido de CPU.
Una vez estamos listos para efectuar la transferencia, en caso de que continuemos en el
modo 1 de trabajo, el Programa nos volverá a mostrar el mismo mensaje que en el caso de la
Descarga, y el usuario podrá proceder de igual modo, si estamos en el modo 2, pasaremos
directamente a enviar el fichero de resultados.
El Fichero de resultados tiene el siguiente aspecto: ‘Resultat.dat’
Amb les Dades:
Risc d'incendi:
Creixement Vegetació:
Error d'extinció:
Incendis Anuals:
Capacitat Extinció:
60
10
92
75
0
Els Resultats són els Següents
Incendis Registrats al Territori:
Mitja Real d'incendis registrats:
Territori Cremat pels Incendis:
Territori Cremat per any:
Incendis extingits pels Bombers:
Incendis majors a 10 hect.:
Incendis majors a 100 hect.:
Incendis majors a 1000 hect.:
69
1430
31
639333
14207
0
228
190
86
El Programa se dispone pues a enviar este fichero.
Vemos que esta vez los cambios en la pantalla han sido mínimos. Nuestro estado ahora es
de preparados para iniciar una descarga, también podemos ver que el panel izquierdo nos
indica que hemos completado un trabajo, y el registro de sucesos tiene constancia de la
transferencia.
Una vez hecho esto ya hemos completado un ciclo normal de finalización de un trabajo,
ahora el programa volverá a iniciar una descarga y vuelta a empezar con el mismo
procedimiento.
70
A.7. Manejando el Control del Programa:
Para empezar hay que decir que el control es simple, pero aún así se presta a errores, ya
hemos explicado como usar la configuración del Programa. Las otras dos opciones son
bastante claras, aún así, si las usamos de manera incorrecta: Continuar cuando estamos en
Marcha, o Parar cuando estamos parados, la aplicación nos lo dirá con un mensaje.
Si usamos bien los controles, y paramos el programa en mitad de la simulación, ocurrirá lo
siguiente:
El estado actual pasa a estar pausado, y el registro deja constancia de nuestra acción.
71
Si ahora decidimos continuar:
Nuestro estado vuelve a pasar a procesando, el registro se actualiza y volvemos a simular.
72
A.8.- Posibles errores en el Funcionamiento:
Con el primer error que nos podemos encontrar durante un ciclo de ejecución es con que
tengamos problemas para descargar un trabajo, ya sea por culpa nuestra, o por la del Servidor.
El programa está preparado para reaccionar ante cualquiera de estos problemas, informar
al usuario debidamente y actuar del mejor modo posible.
Pasaremos ahora a enumerar los posibles errores de conexión y ver como reacciona la
aplicación:
A.8.1. El equipo no tiene conexión a internet:
La aplicación detecta el fallo, para la ejecución del programa e informa al usuario de
que no detecta la conexión a internet con un mensaje de error. El registro también deja
constancia de este hecho.
73
A.8.2. La aplicación no puede conectar con el Servidor.
Si el Programa Servidor está apagado, o porque el Servidor RMI no está registrado, o
simplemente, el Servidor al que intentamos acceder es erróneo, nuestra aplicación Cliente
detecta el problema y inicia un periodo de espera de 10 minutos antes de volver a intentar la
conexión, ya que puede ser que el Servidor este realizando tareas de mantenimiento y vuelva
a estar disponible en breve. Igualmente informa al usuario de que es lo que está haciendo
mediante el siguiente mensaje:
Como hemos visto a lo largo de todo el manual, el registro de sucesos toma nota de lo
sucedido.
Se informa al usuario de que el Programa Cliente volverá a intentar conectar con el
Servidor después de 10 minutos. Realizará hasta 5 reintentos que se irán viendo reflejados
en la pantalla a través de un leve cambio en el mensaje que nos muestran:
74
Si Transcurridos los 5 intentos, el Programa Cliente no ha conseguido establecer la
comunicación con el Servidor, El Programa se parará inmediatamente e informará al usuario
con el siguiente mensaje:
Como podemos observar, toda esta secuencia de acontecimientos queda registrada
nuestro archivo:
75
A.8.3. El Servidor tiene problemas de Mantenimiento:
Detectamos al Servidor, y podemos comunicarnos con el, pero durante la descarga, el
Servidor detecta errores graves que le impiden llevar a cabo la operación. El Servidor
informa al cliente de lo sucedido, y el Cliente parará inmediatamente el programa e
informará al usuario a través del siguiente mensaje.
Registro:
Vemos que el programa ha realizado la petición remota, y la respuesta que ha recibido
del Servidor:
76
A.8.4. El Servidor no Dispone de Trabajos en este momento:
En esta situación, lo mejor es parar el programa Cliente, ya que por muchas peticiones
que enviemos, el Servidor no podrá atenderlas debidamente hasta que introduzca nuevos
trabajos en su BD. Por lo tanto el Cliente informa al usuario de lo que pasa y para el
programa:
Registro:
De nuevo vemos la petición enviada y la respuesta del Servidor:
77
A.8.5. Perdida del Fichero de Datos antes de iniciar el Programa:
Al carecer del Fichero ‘Treball.dat’ es imposible que el simulador pueda cargar los
datos para computarlos. Por tanto la mejor opción es volver a descargar un nuevo trabajo.
Así que pasamos al estado -> Preparado para Descargar.
Registro se actualiza e informa del problema que se ha producido:
A.8.6. Hemos Tardado demasiado en completar el trabajo:
Esto sucede cuando tardamos más de 5 días en completar un Trabajo. Es una medida de
seguridad del Servidor para asegurarse que todos los trabajos se completen. En este caso
simplemente el Cliente informa al usuario de la respuesta del Servidor a través del registro.
Y Pasa inmediatamente a Descargar un nuevo Trabajo. Este caso no aumentará nuestros
trabajos completados
.
78
A.8.7. Perdida del Fichero de Resultados.
El mejor modo de resolver este problema consiste en volver a Simular los mismos datos que
acabamos de simular. Así pues El Cliente pasa al estado Preparados para procesar e inicia el
simulador. Toda esta operación queda registrada
79
A.8.8. Perdida de los Datos del Cliente:
Este error se detecta al cargar la Aplicación, ya que es el momento en que el programa
inicializa las variables que contienen estos Datos a partir de un fichero. En caso de perder el
fichero, el programa al arrancar nos mostraría el siguiente mensaje:
Con este Diálogo el programa
pide al usuario que vuelva a
introducir los datos de su registro
para que el programa los pueda
cargar.
Nos Recuerda también que si
introducimos mal los datos,
perderemos
nuestro
registro
anterior.
Si antes de completar este diálogo
observamos la ventana principal, la zona
reservada a nuestros datos, veremos que ha
cambiado. Todas las variables estadísticas
están a 0, y nuestros Datos en Blanco:
Si no rellenáramos los dos campos de
registro, nos aparecería el siguiente mensaje
en el display inferior:
80
Si Volvemos a rellenar los datos correctamente y pulsamos aceptar, podremos continuar
con la simulación en el punto donde la dejamos antes de perder los datos. Y podremos
observar que la zona de Datos vuelve a estar completa.
Si por el contrario rellenamos mal, bueno, con otro nombre el campo login, nos
encontraremos con un nuevo error.
81
A.8.9. Perdida del Nuestro Registro Cliente en el Servidor
Este error puede ser fruto de que hayamos rellenado mal los campos del error anterior, o
simplemente de que el Servidor haya borrado o perdido nuestros datos.
En ambos casos la respuesta del cliente será la misma:
Nos invitará a registrarnos de nuevo, al hacerlo perderemos nuestros antiguos datos,
pero en realidad, ya estaban perdidos antes. Este Diálogo tiene el mismo funcionamiento que
el Diálogo de registro, solo que también nos permite salir de el y parar el programa, ya que
continuar no podremos sin tener un registro en el Servidor.
Todo queda registrado
82
A.9. Salir del Programa
Para salir del Programa debemos seleccionar la opción de cerrar la ventana. Eso si, el
Cliente nos exige que antes de hacerlo hayamos parado el programa, si lo intentamos hacer
con el programa en ejecución nos encontraremos el siguiente mensaje:
83
Si por el contrario, primero paramos el programa, como podemos observar en la zona de
datos, está parado, nos encontraremos con el Mensaje siguiente:
Este mensaje nos pregunta si realmente queremos finalizar el programa. Si la respuesta es
no, volveremos a la ventana principal, y podremos continuar el simulador mediante el ‘Control
del Programa’. Si la respuesta es SI, el programa guardará todos los datos y se Cerrará.
Hay que tener en cuenta por último que este programa no guarda el estado de la
simulación, es decir, si finalizamos el programa en medio de una simulación, al volver a
ejecutar la aplicación cliente volveremos a iniciar la misma simulación desde el principio. Lo
mismo ocurre con una descarga, o una transferencia.
84
A.10. Programa SimularIncendio
Este es el aspecto que tiene una simulación normal una vez finalizada. Describiremos sus
diferentes componentes:
Datos a Procesar:
Estas son las constantes con las que el simulador trabaja, son las
que descargamos del Servidor.
Territorio:
Aquí podemos ver cual es la evolución, territorio
quemado, vegetación, año tras año.
Gráfica:
La gráfica nos muestra la evolución
que sufre el territorio a lo largo del
tiempo.
85
Resultados:
Aquí podemos ir viendo cuales son
los datos que recogemos mediante la
simulación y que al finalizar
enviaremos al Servidor.
86
ANEXO B : MANUAL DEL SERVIDOR
B.1. Instalación y Requisitos
Para poder ejecutar el servidor en cualquier maquina, además de la máquina virtual Java
(JRE) necesitamos tener instalado mySQL, ya que sino no podremos ni crear la Base de Datos,
ni gestionarla. Por supuesto tenemos que tener creada una Base de Datos.
Para esto ultimo utilizaremos un sencillo programa Java que hará lo siguiente:
public class BD {
public static void main(String[] args) {
Connection conexio;
Statement sentencia;
String name;
String prioritat;
Random prior;
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (Exception e) {
System.out.println("No s'ha pogut carregar el driver de MySQL.");
return;
}
try {
prior = new Random();
conexio = DriverManager.getConnection("jdbc:mysql://localhost/test");
sentencia = conexio.createStatement();
sentencia.execute(
"CREATE TABLE Clients ("
+ " user VARCHAR(10) PRIMARY KEY NOT NULL, "
+ " nom VARCHAR(40) NOT NULL, "
+ " trebComp INTEGER DEFAULT 0, "
+ " data DATE)");
sentencia.execute(
"CREATE TABLE Treballs ("
+ " nomTreball VARCHAR(20) PRIMARY KEY NOT NULL, "
+ " prioritat VARCHAR(1) NOT NULL, "
+ " estat INTEGER DEFAULT 0, "
+ " user VARCHAR(10) NOT NULL, "
+ " data DATE)");
for (int i = 0; i < 7000; i++) {
name = "Simulador" + i + ".txt";
prioritat = "" + prior.nextInt(10);
sentencia.execute(
"INSERT INTO Treballs " + "VALUES ('"+ name + "','" + prioritat + "',0,
'zzzzzzzzzz',null)");
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Creacion finalizada.");
}
}
Crea las dos tablas e introduce todos los trabajos pendientes que tenemos en el directorio
‘Treballs’.
87
Necesitamos también contar con las librerías de Java que nos permiten por un lado servir
aplicaciones RMI, y por otro manejar la Base de Datos a través con mySQL:
Estas dos librerías son generation.jar y mysql-connector-java-3.0.14-productionbin.jar respectivamente.
Para ejecutar la aplicación necesitamos tener en el mismo directorio los siguientes
directorios:
- Treballs -> contiene todos los trabajos pendientes
- Completats -> contendrá todos los trabajos completados
- NoAfegits -> Trabajos no añadidos a la BD
- Backup -> Copias de Seguridad
- Com -> contiene las clases de la librería de mysql-connector-java-3.0.14-productionbin.jar
- Il -> contiene las clases de la librería generation.jar
- Por último el fichero java.policy
Por último antes de ejecutar el servidor tenemos que ejecutar el fichero ‘rmiregistry.bat’
que viene en el mismo directorio que el programa servidor para poder iniciar así el registro
RMI.
De nuevo podemos ejecutar el Servidor de dos formas:
1. Con la maquina virtual java:
Colocando todos los paquetes en el mismo path y que los directorios anteriores y
escribiendo la instrucción:
java -Djava.security.policy=java.policy server.ProgramaServidor
2. Fichero Ejecutable
Generando un fichero ejecutable y colocándolo en el mismo sitio.
Nota: Tanto en el cliente como en el Servidor, podemos ahorrarnos los paquetes il y com
podemos modificando la variable CLASSPATH para indicar donde cual es su path, he
decidido hacerlo así para que el usuario final sólo tenga en ambos casos que ejecutar un
fichero para iniciar la aplicación y no tenga que preocuparse de nada más.
88
B.2. Aspecto
El Programa Servidor en su inicio presenta el siguiente aspecto:
Vemos que podríamos dividir la interficie que se nos ofrece en 4 partes:
B.2.1. La Barra de Tareas:
Contiene Todas las operaciones que es capaz de efectuar el Servidor:
Como vemos se divide en tres menús:
- Servidor : Las operaciones que podemos realizar con el Servidor.
- Mantenimiento de la BD : Operaciones que podemos realizar sobre la Base de Datos
del programa
- Consultar Registre : Operaciones de Consulta de archivos Log o de Trabajos.
89
B.2.2. Zona de Datos
Ocupa la mitad superior izquierda y en ella podemos observar cual es el estado actual
del Servidor. Si esta en marcha o no, cuantos trabajos tenemos en la BD, de que tipo, que
peticiones hay sirviéndose, cuantos clientes hay registrados. Incluso contiene una
‘ALARMA’ que nos indica cuando se producen errores graves que afectan al
funcionamiento del Servidor:
B.2.3. Zona de Registro
Ocupa la mitad superior derecha, en esta zona en blanco se van registrando todos los
sucesos que ocurren mientras el Programa Servidor esta encendido. Dicha información se
guarda una vez al día al menos, y se reinicia el registro.
90
B.2.4. Zona de Consulta de la Base de Datos:
Es la zona más completa de la interficie, nos muestra en todo momento y en tiempo
real cual es el contenido de nuestra Base de Datos. Cada vez que se efectúa un cambio, las
tablas que vemos en esta zona se actualizan.
Podemos observar que hay varios apartados en esta parte. Todos ellos tienen un título
bastante aclarativo, aún así describiremos cada pestaña:
-
Treballs
Es la pestaña que aparece en pantalla por defecto, como vemos consta de una tabla, un
conjunto de opciones para ordenarla, y un botón que reza ‘Guardar’. Este botón sirve para
guardar toda la información que hay en la tabla en un archivo de ‘Log’ para su posterior
consulta. En cuanto a las opciones, son formas de mostrar la tabla ordenada según sus
campos.
La tabla presenta 6 columnas, con las que mostramos todas las características de cada
trabajo. Su nombre, prioridad, Estado, Cliente (en el caso de que este asignado o
completado), fecha (idem), y ubicación (Solo puede tener 2, /Treballs, o /Completats).
Podemos ver que por defecto la tabla se ordena según el nombre del trabajo, pero
veamos que sucede si cambiamos el modo de ordenación, elegiremos prioridad:
Vemos que el orden ha cambiado, y que los primeros trabajos que aparecen, son
aquellos cuya prioridad es más alta ( 9 ).
El resto de pestañas ofrecen un aspecto idéntico, sólo variando en cada caso la tabla
que nos muestran, y las opciones de ordenación.
91
-
Treballs Pendents
Nos muestra los trabajos pendientes. La tabla solo tiene 4 columnas, ya que estos
trabajos no tienen ni Cliente asignado, ni fecha. Por tanto solo pueden ordenarse bajo estas
dos opciones, Nombre y prioridad.
-
Treballs Assignats
Trabajos asignados, permiten ser ordenados por nombre, cliente y fecha, por prioridad
no es interesante, ya que la prioridad es un factor que se tiene en cuenta solo en los
trabajos pendientes. Obsérvese que se presenta ordenado por el Login del Cliente.
-
Treballs Completats
Trabajos completados, igual que los asignados.
Obsérvese que se presenta ordenado por la fecha de finalización.
92
-
Clients
Esta otra tabla nos muestra cuales son los clientes que tenemos registrados en la Base
de Datos, así como los datos que conocemos de ellos, es decir, su Login, nombre, trabajos
que ha completado y la última fecha en que se conectaron. Estos son, en esta tabla, los
posibles parámetros de ordenación
-
Avisos Importants.
Esta pestaña difiere y mucho de las anteriores ya que no se trata de una tabla. Consiste
en un registro de avisos críticos, es decir, avisos que afectan al funcionamiento del
programa y deben ser corregidos inmediatamente. Se complementa con la ALARMA que
hemos visto en la ‘Zona de Datos’, y nos permite borrar el contenido del registro, y
también, como el resto de pestañas, guardarlo en un fichero.
Cuando se produce un error Critico, la ALARMA (flecha 1), que cambia a ROJO, nos
indica que se ha producido, y en la segunda flecha, aparecerá reflejado el problema. Una
vez visualicemos el problema, la alarma se apagará.
Una vez hemos visto cuales son las componentes de la interficie, vamos a ver como
actúan.
93
B.3. Funciones de la Barra
Veremos las funciones de la Barra a través de cada uno de sus Menús.
B.3.1. Funciones del Menú Servidor
Empezaremos por ver cuales son las funciones que nos ofrece este menú:
Podemos efectuar dos acciones:
-
Iniciar el Registro RMI
Esta función nos permite registrar nuestro Servidor en RMI, con lo que estamos listos
para aceptar peticiones remotas. El registro de sucesos actualiza sus datos, mientras que el
estado de nuestro Servidor pasa a ser ‘En marcha’.
-
Parar el Registro RMI
Esta función anula nuestro registro en RMI, con lo que ya no podemos aceptar
peticiones remotas, esto se refleja gráficamente de la siguiente forma:
94
Son unas funciones muy simples y sencillas, aún así pueden usarse mal, si esto
ocurre, el Servidor simplemente nos lo indica con un Mensaje de Error
Si lo paramos y está parado
encendido
Si
95
lo
encendemos
y
esta
B.3.2. Funciones del Menú de Mantenimiento de la BD
Estas son las operaciones que este menú nos proporciona:
Podemos ver que este menú es algo más completo que el anterior, ya que la Base de Datos
requiere una atención mucho más compleja que el registro del Servidor. Vemos que es un
abanico bastante completo de funciones, quizá podemos pensar que falte la de insertar un
cliente, pero esa ya se efectúa directamente con la función remota que lleva ese nombre.
Pasaremos a ver que ocurre cuando efectuamos cada una de estas operaciones:
-
Añadir un Trabajo:
Esta operación despliega ante nosotros el siguiente Dialogo:
El Diálogo consta de una tabla donde podemos encontrar todos los trabajos que el
Servidor tiene disponibles para ser añadidos a nuestra Base de Datos, son los que se
encuentran en el Directorio ‘NoAfegits’, también nos permite seleccionar la prioridad con
que queremos que se guarde el nuevo trabajo.
96
El Botón Backup, nos permite acceder al directorio que contiene todas las copias de
seguridad de todos los trabajos que contiene la BD, y de los que se pueden añadir. Y
desde allí añadir el fichero a nuestra BD. Esto es para casos de perdida o deterioro de los
ficheros asociados a los trabajos. El funcionamiento de la operación para este caso seria el
mismo que el anterior, seleccionar un trabajo, una prioridad y pulsar la opción aceptar. La
opción cancelar deja nuestra operación sin validez.
En caso de que la operación se realice con éxito, por ejemplo, “insertar el trabajo
Simulador7010 con prioridad 9”, el programa lo reflejaría de la siguiente manera:
Podemos observar que dejamos constancia de la operación en el registro de sucesos, y
que el trabajo aparece inmediatamente en su respectiva tabla. También se modifican los
campos ‘Trabajos totales’ y ‘Trabajos pendientes’ de la zona de datos, aumentando ambos
en 1.
97
-
Borrar un Trabajo
Desplegamos el siguiente cuadro:
Este cuadro nos presenta una tabla en donde se listan todos los trabajos que contiene
nuestra base de Datos, tanto los pendientes, los asignados como los completados. Es
decir, podemos elegir cualquier trabajo para borrar. También nos ofrece la posibilidad de
borrar el fichero asociado, en cuyo caso eliminaremos el fichero del directorio ‘Treballs’,
en caso de que no eliminemos el fichero, este pasará a ‘NoAfegits, para añadirlo
posteriormente si se desea.
98
Veamos que sucede si borramos el trabajo Simulador7010 con prioridad 9, pero no
borramos su fichero asociado.
Como vemos el fichero ha desaparecido de la Base de Datos, y el registro de sucesos
ha tomado nota de nuestra operación. Los Trabajos Totales, y Pendientes también han
sido modificados.
99
Veamos pero que pasaría si eligiéramos la opción de borrar también el fichero
asociado, es decir marcar la siguiente casilla:
Este sería el resultado:
Como vemos, el mensaje que ahora aparece en el registro es diferente, y nos indica
que su fichero asociado también se ha borrado. El resto es igual que en el caso anterior.
Esta vez, ya no encontraremos el fichero Simulador7010 para añadirlo a no ser que
elijamos la opción ‘Backup’.
100
-
Cambiar la prioridad de un Trabajo
El Diálogo de cambio de prioridad es bastante parecido en su aspecto al de añadir un
fichero. En este en cambio, los trabajos que se muestran en la tabla son los trabajos
pendientes, y cada uno de ellos con su prioridad. Para efectuar la operación, únicamente
tenemos que seleccionar un trabajo y elegir su nueva prioridad mediante el combo y
seleccionar aceptar. En caso de arrepentirnos, podemos pulsar cancelar, con lo que
anularemos la operación.
101
Este sería el resultado de cambiar la prioridad del trabajo Simulador1 a 9.
De nuevo, el registro se actualiza con los nuevos acontecimientos, y también
observamos que la tabla de Trabajos pendientes se ha actualizado con el cambio, la tabla
de Trabajos, también se ha actualizado.
102
-
Borrar un Cliente
Esta operación puede realizarse para liberar espacio en nuestra BD, por ejemplo si
observamos que un cliente lleva mucho tiempo sin conectar, podemos suponer que ya no
ejecuta su programa Cliente.
Si Elegimos esta operación, esta será la pantalla que aparecerá:
103
Podemos ver que en este caso la Tabla nos muestra a todos los clientes que tenemos
registrados en nuestra BD. Si por ejemplo elegimos borrar al Cliente Frikimen, Este sería
el resultado que observaríamos gráficamente:
Como cada operación, esta también se registra en los sucesos. Además observamos
que la tabla clientes ya está actualizada, puesto que no aparece ‘Frikimen’ y el campo
Clientes Registrados ha disminuido en una unidad.
104
-
Revisar la Base de Datos
Es una función que hay que realizarla cuando desde el Servidor se nos indica que
puede haber anomalías en la BD. Tales como trabajos sin fichero o cosas así. Esta función
recorre la Tabla Treballs comprobando que todo este en orden.
Podemos encontrarnos con dos posibles resultados de esta operación:
1. No encontramos ninguna anomalía:
En este caso lo único que sucede es que actualizamos el registro de sucesos:
2. O bien que el Servidor encuentra anomalías en la BD y las corrige:
105
Como vemos este Resultado es mucho más llamativo, para llamar la atención del
administrador. Vemos que aparece un Diálogo de Error, una nota en el Registro de
Sucesos, incluso se enciende la ALARMA de sucesos Críticos. No es que vaya a dejar de
funcionar el Servidor, pero se intenta que el administrador tenga en cuenta este resultado.
El Mensaje de Error nos dice que consultemos el fichero de Log donde ha dejado los
datos de las correcciones.
-
Recuperar la Conexión
Esta última opción es muy simple, pero de vital importancia. Lo único que hace es
restablecer la conexión del programa con la BD, al hacerlo permite el funcionamiento de
Servidor. Se debe accionar siempre que el Servidor nos informe que se ha producido un
error con MySQL, o siempre que reiniciemos el propio MySQL. Lo único que ocurre
gráficamente es que se actualiza el registro:
106
B.3.3. Funciones del Menú de Consulta
-
Ver Archivo de Log
En cualquier momento el administrador puede tener la necesidad de saber que ocurrió
con una determinada situación en el pasado, o simplemente ojear datos de días anteriores,
para esto el Servidor lleva un registro de todo lo que acontece en el Programa, y además
se ofrece la posibilidad al administrador de realizar determinadas operaciones que
también generan archivos de Log. Revisar la BD, Guardar Tablas...
El Diálogo que nos permite acceder a este contenido nos muestra en principio el
contenido del Directorio Log, que consiste en un montón de fechas que corresponden a
los días en que el Servidor ha estado activo. Seleccionamos el día que queremos consultar
y pulsamos ‘Abrir’.
107
En ese momento el Cuadro principal del Diálogo cambiará para mostrarnos los
archivos Log que tenemos guardados de ese día: Si tenemos todos los archivos el aspecto
del Diálogo será el siguiente:
Podemos ver aquí todos los archivos de Log de que podemos disponer. Si nos
arrepentimos y queremos volver atrás, no tenemos más que elegir la opción ‘Subir un Nivel’
en ese caso volveremos a la situación anterior.
Estos son los tipos de archivo de Log que nos podemos encontrar y como nos los muestra el
Servidor:
108
•
AvisosImportants.log
•
ClientsRegistrats.log
109
•
Incidencies.log
•
RenovacióBD.log
110
•
RevisioBD.log
•
Treballs.log
111
•
TreballsAssignats.log
•
TreballsPendents.log
112
•
TreballsCompletats.log
Todos estos diálogos son simplemente de consulta, no podemos realizar ninguna
operación con ellos. Una vez hemos encontrado lo que buscamos, pulsamos aceptar y
volvemos a la ventana principal del Servidor.
113
-
Ver Trabajo
Las tres operaciones restantes se desarrollan del mismo modo. Tanto si elegimos ver
un archivo Pendiente, Asignado, o Completado, el cuadro que nos aparecerá será el que
vemos a continuación. Solo Cambiará el contenido de la Tabla. Que nos listará los
trabajos que hayamos solicitado en cada caso.
114
Así pues una vez hemos seleccionado el trabajo que deseamos visionar nos
encontramos con lo siguiente:
•
Si hemos elegido visionar un Trabajo Pendiente, o Asignado veremos algo así:
Este es el contenido de cualquier trabajo de este tipo, el valor de las 5 variables que el
simulador del programa cliente necesita para Simular Incendios.
•
Si hemos elegido visionar un Trabajo Completado nos aparecerá lo siguiente:
Cualquier trabajo completado nos mostrará los siguientes datos, que son el
resultado de una Simulación completa de 45 años sobre un territorio aplicando a ese
territorio las variables que aparecen arriba.
115
B.4. Tratamiento de los Trabajos Caducados
Ya hemos visto algo de este apartado en este informe, concretamente el fichero de log que
se genera al realizar esta Tarea.
En este aparatado explicaremos en que consiste esta función:
La principal misión del Servidor es, además de que todo funcione correctamente en todo
momento, procurar que todos los trabajos se completen lo antes posible, un impedimento para
esta tarea es el hecho de que algún cliente deje de utilizar la aplicación, y tenga un trabajo
asignado, este trabajo no se completaría nunca, ya que el Servidor sólo puede enviar trabajos
pendientes.
El sistema ideado para solucionar esto es ejecutar una vez al día una tarea que vuelva a
dejar en el estado de pendientes todos aquellos trabajos que lleven más de 5 días asignados.
De esta forma podremos volver a enviar el trabajo.
Esta tarea se ejecuta una vez al día entre las 23 y las 0 horas y deja constancia de su
actuación en el registro.
-
Si no encuentra Trabajos de este tipo el único rastro que dejará esta tarea estará en el
registro:
116
-
Si en cambio la tarea encuentra trabajos caducados el administrador se encontrará con
este mensaje:
Por supuesto también se actualizarán todas las tablas correspondientes, Trabajos,
Pendientes y Asignados, así como en los Datos del Servidor, las etiquetas que se refieren
a estos trabajos.
117
B.5. Comunicación entre la Funciones Remotas y el Administrador:
A continuación veremos los diferentes mensajes que el Servidor puede dejar en el
registro, y en caso de errores graves, como avisa al administrador:
B.5.1. La operación se realiza con éxito
En este caso nos podemos encontrar con los siguientes mensajes en el registro,
dependiendo de la función remota de que se trate:
Aquí podemos ver una secuencia completa de las 3 operaciones remotas realizadas con éxito.
Primero el registro del nuevo Cliente, después la petición de descarga, y por ultimo la
petición de transferencia
B.5.2. El Trabajo enviado, estaba caducado
Este dato es irrelevante para el administrador, aún así queda constancia de ello en el
registro.
118
B.5.3. Acceso no autorizado
Cuando un cliente no registrado intenta acceder al Servidor, este se lo impide, y le da
orden al Cliente de que registre al usuario antes de seguir, el mensaje tanto en descargas como
en envíos queda en el registro. En descargas se asume que es el cliente el que no esta
registrado, y en envíos se da por echo que es el Servidor el que ha perdido los datos, el
resultado es el mismo.
B.5.4. El Servidor se ha quedado sin Trabajos
Este tipo de situación es más grave, ya que el administrador debe reaccionar y añadir
nuevos trabajos para que los clientes puedan descargar, ya que sino los tendría a todos
desaprovechados.
Por este motivo este error activa la ALARMA ya que se trata de una situación que hay
que remediar rápidamente
119
B.5.5 No se puede encontrar un directorio
Este caso es similar al otro, ya que la perdida de un directorio entero nos impide acceder a
los ficheros asignados a los trabajos, y por tanto, nos impide enviar ficheros a los clientes. Por
tanto el administrador debe recuperar todos los ficheros a partir de las copias de seguridad.
Resumiendo, tenemos que activar la alarma.
120
B.5.6 Perdida de un fichero
Este no es un error crítico, pero se activa la alarma igualmente para que el administrador
tenga constancia de este hecho y pueda recuperar el fichero más tarde. El trabajo se elimina
de la Base de Datos precisamente para poder recuperarlo más tarde.
121
B.5.7. Error de acceso a la BD
De nuevo nos encontramos con un error crítico, ya que si no tenemos acceso a la Base de
Datos no podemos acceder ni a trabajos, ni a Clientes, y el Servidor pierde toda su
funcionalidad.
Por ello este error, de nuevo crítico tiene que hacer reaccionar al administrador rápidamente,
así que activamos la alarma y mostramos un mensaje de error por pantalla para captar la
atención del administrador.
Si abrimos la pestaña de avisos importantes, nos encontraremos con este mensaje:
Obsérvese que al abrir la pestaña, la alarma desaparece.
122
B.6. Errores durante las operaciones de Mantenimiento
Durante las operaciones de mantenimiento de la Base de Datos se pueden producir tres
tipos de errores que ya hemos visto en el apartado anterior. La reacción del programa ante
estos errores será muy similar al que hemos visto, pero complementarán el aviso con un
mensaje de texto sobre la pantalla:
Estos son los errores que nos podemos encontrar mientras realizamos operaciones de
mantenimiento, y las respuestas del Programa:
B.6.1. Perdida de la conexión con la Base de Datos.
Este error también se genera cuando se detecta cualquier tipo de fallo de acceso a la Base
de Datos cuando estamos consultando las Bases de Datos a través de la tablas de la Zona de
Consulta de la Base de Datos.
123
B.6.2. Perdida del Fichero
B.6.3. Perdida de un Directorio (NoAfegits, Backup, Treballs o Completats)
124
B.7. Errores en la Consulta de archivos
Al Consultar un archivo nos podemos encontrar de nuevo con 3 tipos de Errores, dos los
hemos tratado ya en el apartado anterior, y la reacción del programa es la misma, aunque
difieren los mensajes que se registran en sucesos. Son la perdida del fichero, y la perdida del
directorio. (Treball, Completas, o Log).
El único error nuevo que nos podemos encontrar al consultar un fichero, es que este haya sido
modificado. En este caso el programa nos informara de la alteración con un mensaje de error
y registrándolo. No se activará la alarme ya que no es un error tan grave, ni siquiera que
merezca reparación.
125
B.8. RMI no Registrado
Un error muy frecuente que nos podemos encontrar es que nos olvidemos de poner en marcha
RMI antes de ejecutar la aplicación Servidor, o bien que el Servidor RMI se caigo (esto es
poco frecuente). En este caso el administrador debe ser avisado inmediatamente para que
corrija el problema ejecutando RMI, ya que sino no podremos registrar nuestro Servidor.
También contamos con una tarea que cada 15 minutos comprueba que RMI este funcionando,
y nuestro Servidor Registrado. Si no es así avisa al administrador.
La manera de hacerlo es la de siempre, ALARMA, Mensaje de Texto y registrarlo.
126
B.9. Errores de Arranque
Por último trataremos los 2 errores que podemos encontrarnos al Arrancar la aplicación.
En cualquier error de este tipo, el programa nos mostrará una pequeña pantalla con el tipo de
error y nos invitará a Salir, ya que es imposible que se cargue el programa bajo esas
condiciones. Una vez hayamos arreglado el problema, podremos ejecutar la aplicación.
Podemos tener dos problemas:
-
MySQL no está en funcionamiento
-
Ya existe una copia del Programa Servidor en Funcionamiento
Ya como último apunte me gustaría comentar que todos los diálogos, al igual que en el
Cliente son manejable con el teclado.
127
B.10. Salir del Programa
Para salir del Programa Servidor tenemos que utilizar la opción de Cerrar la ventana principal
del Programa. Para poder Salir, el Servidor RMI tiene que estar parado, en caso contrario, el
Programa no nos dejará cerrar.
Si Primero paramos el Servidor RMI y luego Salimos el resultado será este.
Si queremos Cerrar pulsaremos Si, y si queremos volver al Programa pulsaremos no.
128
0.- INDICE
1. Introducción y Objetivos
1.1. Introducción
1.2. Objetivos
1
1
1
2. Antecedentes
2.1. Computación Distribuida
2.2. SETI@home
2.3. Aplicación Servidor-Cliente
2
2
3
3
3. Tecnologías utilizadas
3.1. Java
3.2. RMI
3.3. Swing
3.4. mySQL
3.5. JDBC
3.6. Eclipse
3.7. Jsmooth
4
4
5
7
8
8
9
9
4. Análisis
4.1. Análisis de la interacción Cliente-Servidor
4.1.1. Descargar Fichero
4.1.2. Enviar Fichero
4.1.3 Registrar Cliente
4.2. Análisis del Cliente
4.2.1. Bucle Principal
4.2.2. interfazGráfica
4.2.3. Programa de Cálculo Intensivo
4.3. Análisis del Servidor
4.3.1. Base de Datos
4.3.2. Funciones Remotas
4.3.3. interfazGráfica
10
11
11
12
12
13
13
13
13
14
14
14
15
5. Diseño
5.1. Diseño de las Funciones Remotas
5.1.1 Protocolo de Transferencia
5.1.2. Servidor.java
5.2. Diseño del Cliente
Dades.java
5.2.1. Diseño del Bucle Principal
5.2.1.1. DialogNoConexio.java
5.2.1.2. DialogFiIntents.java
5.2.1.3. DialogError.java
5.2.1.4. DialogConfirmacio.java
5.2.1.5. DialogPerduaRegistre
5.2.1.6. DialogNoTreballs
5.2.1.7. Bucle.java
5.2.2. Diseño de la interfazGráfica del Cliente
5.2.2.1. PanelDaltEsqEtiqs.java
5.2.2.2. PanelDaltDret.java
5.2.2.3. PanelDaltEsqBotons.java
5.2.2.4. DialogConfiguracio.java
5.2.2.5. DialogFinal.java
5.2.2.5.1. DialogClose.java
16
16
16
17
19
19
20
20
20
20
21
21
21
22
25
26
26
27
27
28
28
129
5.2.2.6. DialogPerduaDades.java
5.2.2.7. DialogNoArranc
5.2.2.8. DialogRegistre
5.2.3. Diseño del Programa de Calculo Intensivo
5.2.3.1. Variables.java
5.2.3.2. Cua.java
5.2.3.3. InterficieCalcul.java
5.2.3.4. SimularIncendis.java
5.3. Diseño del Servidor
Dades.java
5.3.1. Diseño de la Base de Datos
5.3.1.1. MetodesBD.java
5.3.2. Diseño de la interfazGráfica del Servidor
5.3.2.1. Barra de Menús
5.3.2.1.1. Menú Servidor
ComprovacioRMI.java
Iniciar Servidor
Parar Servidor
DialogPeticioEnCurs.java
5.3.2.1.2. Menu BD
Añadir Trabajo
DialogAfegir.java
Borrar Trabajo
DialogBorrar.java
Borrar Cliente
DialogBorrarClient.java
Cambiar la Prioridad de un Trabajo
DialogCanviPrioritat.java
Revisar la Base de Datos
RevisarBD.java
Recuperar la conexión
RecuperarConexio.java
ComprovacioCaducitat.java
5.3.2.1.3. Menu Consulta
Consultar una archivo de Log
DialogConsulta.java
DialogVeureArxiu.java
Consultar un Trabajo
DialogResultats.java
DialogVeureTreball.java
5.3.2.2. Zona de Control del Estado del Servidor
PanelDaltEsq.java
DanelDalDret.java
5.3.2.3. Zona de Control de la Base de Datos
PanePanel1.java
PanePanel2.java
PanePanel3.java
PanePanel4.java
PanePanel5.java
PanePanel6.java
DialogError.java
DialogFinal.java
DialogTancament.java
DialogNoInici.java
DialogNoSQL.java
130
28
28
29
30
31
31
32
33
35
36
37
38
41
41
41
41
42
42
42
43
43
43
45
45
46
46
47
47
48
48
48
48
49
50
50
50
51
52
52
52
53
53
53
54
54
55
55
55
55
55
56
56
56
56
56
6. Conclusiones
57
7. Bibliografía
59
Anexo A : Manual del Cliente
A.1. Instalación y Requisitos
A.2. Bienvenido al Programa
A.3. Registro Completado
A.4. Primera Ejecución
A.5. Configuración del Programa
A.6. Ejecución del Programa
A.7. Manejando el Control del Programa
A.8. Posibles Errores en el funcionamiento
A.8.1. El Equipo no tiene conexión al internet
A.8.2. La Aplicación no puede conectar con el Servidor
A.8.3. El Servidor tiene problemas de Mantenimiento
A.8.4. El Servidor no dispone de Trabajos en este momento
A.8.5. Perdida del Fichero de Datos
A.8.6. Hemos tardado demasiado en Finalizar un Trabajo
A.8.7. Perdida del Fichero de Resultados
A.8.8. Perdida de los Datos del Cliente
A.8.9. Perdida de nuestro Registro Cliente en el Servidor
A.9. Salir del Programa
A.10. Programa Simular Incendio
Anexo B : Manual del Servidor
B.1. Instalación y Requisitos
B.2. Aspecto
B.2.1. La Barra de Tareas
B.2.2. Zona de Datos
B.2.3. Zona de Registro
B.2.4. Zona de Control de la Base de Datos
Trabajos
Trabajos Pendientes
Trabajos Asignados
Trabajos Completados
Clientes
Avisos Importantes
B.3. Funciones de la Barra
B.3.1. Funciones del Menu Servidor
Iniciar el Registro RMI
Parar el Registro RMI
B.3.2. Funciones del Menu de la BD
Añadir Trabajo
Borrar Trabajo
Cambiar la Prioridad e un Trabajo
Borrar un Cliente
Revisar la Base de Datos
Recuperar la Conexión
B.3.3. Funciones del Menú de Consulta
Ver un archivo de Log
Ver un archivo de Trabajo
B.4. Tratamiento de los Trabajos Caducados
B.5. Comunicación entre Funciones Remotas y Administrador
B.5.1. La operación se Realiza con éxito
B.5.2. El Trabajo enviado estaba Caducado
131
60
60
61
62
63
65
66
70
72
72
73
75
76
77
77
78
79
81
82
84
85
85
87
87
88
88
89
89
90
90
90
91
91
92
92
92
92
94
94
96
99
101
103
104
105
105
112
114
116
116
116
B.5.3. Acceso no autorizado
B.5.4. El servidor se ha quedado sin Trabajos
B.5.5. No se puede encontrar un directorio
B.5.6. Perdida de un Fichero
B.5.7. Error de acceso a la BD
B.6. Errores durante el Mantenimiento de la BD
B.6.1. Perdida de la Conexión con la BD
B.6.2. Perdida del Fichero
B.6.3. Perdida de un Directorio
B.7. Errores en la Consulta de Archivos
B.8. RMI no Registrado
B.9. Errores de Arranque
B.10. Salir del Programa
132
117
117
118
119
120
121
121
122
122
123
124
125
126
Descargar