Cómo crear tu propio Twitter con NoSQL

Hacía tiempo que tenía ganas de escribir algo sobre NoSQL ( Not only SQL ), y algunos clientes me han pedido que les programara una red social varias veces,…desde que Twitter empezó a usar este tipo de base de datos porque MySQL ya tenía hacía un tiempo algunos problemas de latencia, debido a la gran cantidad de datos nuevos a indexar, …pensad que en un día como hoy se generan más de 12 TeraBytes de información de los twitts, es decir, aproximadamente 4 PetaBytes al año, estamos hablando del 2010 y estos datos se doblan cada año, pues multiplicad por 6…casi ná!

Me pregunté , ¿Cómo debería un programador php freelance construir una red social como Twitter o Facebook?

¿Qué hacer con semejante volumen de datos y tenerlo todo ordenado e indexado?, es una tarea colosal, ¿verdad? ,pues bien, los chicos de Twitter nos contaron en el evento Strange Loop de 2010 ( video + audio | pdf  ) que diseñaron estrategias mixtas de bases de datos con NoSQL ,donde MySQL no llegaba a ser suficiente, imagino que los cortes en el servicio de por aquellos entonces tuvieron mucho que ver con esto…normal. Estas estrategias se basan en construir un sistema o arquitectura de sistemas de información integrados…pero…Por qué llegaron a usar NoSQL en Twitter: porque necesitaban recoger todos los datos de forma eficiente de millones de usuarios, guardarlos y analizarlos, algoritmos capaces de “aprender” acerca de la información de estos datos para saber cómo tratarla y optimizarla – indexarla, análisis de grafos sociales, etc.

Luego los problemas a solucionar eran: 1. recoger datos, 2. guardar y analizar los datos, 3. aprendizaje rápido de datos masivos
Ahora comentaré un poco esta presentación:

 

1. Recoger datos masivos [logs]

Empezando por el escritor de logs, empezaron usando syslog pero no era escalable, se colgaba y se perdían datos, por lo que usaron Scribe montado sobre Apache Thrift que si es escalable y también usado por Facebook, es un framework de código abierto que escribe líneas de datos en categorías y hace mucho trabajo por nosotros, ya que colecciona datos de diferentes máquinas en un clúster funcionando de forma local y en red, de forma que se administra para no perder los datos de los nodos, es escalable, jerárquico y permite conectar salidas externas de los datos fácilmente…de modo que usar esta tecnología solucionó el primero de los problemas. Como en Twitter son muy majos, extendieron el framework opensource mejorando la escritura, compresión, monitorización y escritura en HDFS continuando el trabajo con parches de FB lo que hizo posible almacenar más de 12TB al día sin que fuera un drama.

 

2. Guardar y analizar datos masivos

Sí, el que escribe ha mencionado HDFS que viene de Hadoop, un framework para guardar los datos de forma distribuída, es decir, una técnica que permite escribir todos esos datos masivos en un clúster de máquinas, porque ,en fin, ya sabéis que no hay disco duro que pueda escribir tantos datos tan rápido, …por ahora…

Guardar los datos

Esto es algo complejo porque un sistema así necesita replicación automática y tolerancia a fallos, algo que soporta Hadoop. Hay que pensar que esta arquitectura de información funciona como un gran disco duro compartido entre diferentes nodos.

Analizar los datos

 

Además permite MapReduce una tecnología de Google ( ya sabéis que este tiene servidores de alta replicación y aplicaciones distribuidas –google app engine– ) , basado en computación paralela y el par llave-valor de amplio rango…por ejemplo Yahoo! tiene un clúster de 4000 nodos, es capaz de ordenar 1 TB de números aleatorios (índices) en 62 segundos, y además permite empaquetar fácilmente gracias a Cloudera RPM (donde está ahora el creador de Hadoop).

Ejemplo de MapReduce

Ejemplo de MapReduce

Un ejemplo del uso de MapReduce sería una consulta para saber cuántos tweets tiene un usuario, obteniendo los datos de la tabla de tweets, se le pasa una llave que es la columna y el valor es la información del tweet, el mapa de salida tiene una llave que es el id de usuario y un valor numérico, se barajan los datos ordenándolos por este id de usuario y se reducen por la misma razón, una máquina puede hacer esto fácilmente, varias máquinas nos devuelven los datos más rápido, mientras más se usen más rápidamente se devuelve el resultado, la cuestión es cómo balancear la carga…

Uno de los retos sería analizar datos de grafos sociales en relaciones entre usuarios, por ejemplo, los seguidores de alguien, es imposible hacer una consulta MySQL con un self join de una tabla con n-millones de filas…entonces se usa el clúster para hacer más fácil distribuir cálculos que se trata de la diversión que proporciona la computación paralela :D

Hacerlo de esta forma significa que puedes contar todos los tweets, es decir, los más de 20 millones en 5 minutos aproximadamente…

 

3. Aprendizaje rápido de datos masivos

Obtener datos rápidamente de datos masivos

¿Cómo están estructurados los datos almacenados?, están los datos semi-estructurados: logs de apache, logs de consultas, logs RoR, tests A/B, etc., y luego están los datos estructurados: tweets, usuarios, bloques, teléfonos, favoritos, búsquedas guardadas, etc. , por último están los datos complejos: grafos sociales, esto último me pareció lo más interesante pues es algo que usamos todos en twitter, cuando buscamos en la red social información sobre un meta-tag o un usuario o una palabra por ejemplo (conteno, mínimo, máximo, etc.), se devuelve un resultado basado en cientos o miles de capas de información por los que viajan indagando en nuestra consulta…

En este caso, el sistema que utilizan en Twitter para hacer la indagación es conocido como Apache Pig , basado en un lenguaje de alto nivel , capaz de transformar datos de conjuntos y registros y procesarlos mediante transacciones, el lenguaje de pig es un poco diferente al SQL que conocemos…y es normal ya que cuando tienes un fichero muy grande, y que se ha transformado en un conjunto de registros, hay que especificar algunas cosas ,aunque es bastante fácil de entender, veamos un ejemplo de un script que nos propone Kevin Weil en su presentación:

scrip_pig

es un script para contar los 5 primeros tweeteros entre 18 y 25 años ordenados por mayor número de seguidores  y agrupados por urls, se hace un joint, un group y un order limitándolo a 5…esta consulta realizada en Hadoop ocuparía como 100 veces más en código lo cual es algo que nos dice lo que nos estamos ahorrando, de hecho…Pig democratiza el análisis de datos a gran escala, lo que significa usar el 5% del código y el 5% del tiempo que se tardaría normalmente además está optimizado hasta un 20% en tiempo de ejecución, pero, y siempre hay un pero xD,  depende del tipo de consulta que hagas, claro,…debido a lo importante que es ahorrar recursos se preparan muy bien las preguntas, aún así, se utilizan mecanismos automáticos de medida de latencia media, distribución geográfica, etc. que ayudan a recuperar la respuesta más eficientemente…

Aquí un ejemplo de script para buscar con Pig  una url

script_pig_url

Aprendizaje

Es precisamente saber qué consulta hacer lo que le da valor al sistema,y esto sirve para promover la innovación que necesita cada iteración ,al ingeniero, de forma que mientras mejores preguntas y más personas integren el equipo de mejora, más rápido mejorará el sistema.

Resumiendo, en el eco-sistema de Twitter tienen Cloudera: es una distribución libre que se usa desde 2010 en combinación con CDH2 y Hadoop, esto junto con Scribe y LZO, que es ideal para comprimir los datos que se escriben en el HDFS; y, MapRedude implementado en Java (HBase, Hadoop streaming, etc)

Para que las máquinas sepan relacionar mejor los datos se utilizan algoritmos probabilísticos , de covarianza e influencia, algunos criterios por ejemplo serían el uso por parte de clientes de escritorio, móviles y web, correlaciones importantes cuando hablamos de grandes volúmenes de datos.

¿Cómo se puede aprender de lo que los usuarios escriben en twitter?

Evidentemente los fallos del sitio son oportunidades únicas para aprender,

  • ¿qué es lo que fué mal al mismo tiempo?
  • ¿ qué es lo que más se utilizó por parte de los usuarios?
  • A/B testing, etc.

conociendo las preguntas, entonces se pueden buscar correcciones y sugerencias de cambios como respuestas.

Para aprender, las preguntas correctas que debemos formular serían:

  • ¿qué está diciendo un usuario?
  • ¿y sus seguidores?
  • ¿y los usuarios a los que sigue?
  • ¿qué nos dice el ratio de seguidores/seguidos?
  • ¿de qué idioma se trata?
  • ¿son reconocibles los términos utilizados?

y etc.,…estas preguntas generan un gran flujo de información que resulta, entre otras cosas, en la creación de grafos sociales y que nos dan una idea directa de información como puede ser la reputación de ese usuario, de su influencia, en definitiva lo que se aprende son datos aplicables al aprendizaje que pueden ejecutar computadoras.

Estos datos se pueden analizar para buscar patrones, por ejemplo, se puede usar el programa de la FOCA de nuestro hacker español Chema Alonso y descubrir el patrón de movimiento de un usuario gracias a los tweets con meta-información que nos permiten estar geolocalizados, de manera que en un mapa aparecerán nuestras rutas por semana y cosas por el estilo. Otro ejemplo práctico para los administradores de la red social es poder encontrar bots, este script es un ejemplo de cómo se haría:

script_encuentra_bots_pig

 

 

Y hasta aquí he hablado un poco sobre lo que dijo Kevin en 2010 pero si tenéis ganas de más, hay mucho más!, de hecho dentro de muy poco dará lugar un evento acerca del estado actual de NoSQL, en la NoSQL Now! 2013 Conference. Con ponentes de Amazon (que da soporte a Apple y su iCloud por ejemplo), GitHub, RackSpace, etc., y allí contarán las cosas que están de moda jeje

Para nosotros simples mortales con proyectos webs que no alcanzan los millones de visitas al día, ¿qué podemos utilizar?, pues bien, hay varias soluciones, entre las que cabe destacar, además de las utilizadas por Twitter ( Cassandra y Cloudera ), está MongoDB, HyperTable, etc., depende del uso que se le vaya a dar, más información acerca de las más de cien implementaciones de NoSQL en nosql-database.org , de hecho se estuvo estudiando el uso de este tipo de base de datos para WordPress pero como se requiere un grado mayor de relaciones entre entidades no sería tan eficiente y se descartó…

Si lo que queréis es usar PHP y una base de datos NoSQL hay una implementación de API’s para muchas de ellas, por ejemplo para HyperTable, CouchDB, etc., para esta última tenemos PHPillow, pero lo importante es preguntaros para qué las váis a usar, si es para guardar

  • pares de llave/valor ( Riak, Redis, memcached, BigTable etc.)
  • muchas columnas – XML – ( Cassandra, BaseX, eXist, MarkLogic Server etc.)
  • documentos (CouchDB, Jackrabbit, MongoDB, OrientDB, SimpleDB,Terrastore, etc)
  • grafos -objetos- ( AllegroGraph, DEX, Neo4j, FlockDB, Sones GraphDB etc.) , XML

cada una tiene una disponibilidad de los datos (ver teorema de CAP), consistencia y tolerancia de particiones (fallos) diferente, por ejemplo para una bd distribuida basada en pares de llave/valor como Redis se podría escribir un script como este en PHP:

$redis = new PredisClient(9;
$redis->set('miLlave', 'Un valor');
$valor = $redis->get('miLlave');

ok, pues extrapola esto y constrúyete tu propio clon twitter con Redis jaja.

Sin embargo con la aproximación por columnas se puede crear un modelo relacional a medida, tomando como base dimensiones o categorías:columnas_bd_nosqlesto se puede hacer con Cassandra, deberías usarla siempre que necesites guardar más que leer, y que los datos tengan una gran disponibilidad, además trae soporte de Hadoop como hemos visto antes. Hay diferentes implementaciones en PHP como es el caso de phpcassa.

Aquí un ejemplo del uso de los índices de columna de Cassandra escrito en PHP:

 

//Conectar con el espacio de llaves
$basedatos = new ConnectionPool('mi-bd-twitter');
 
//Crear la familia de columnas de usuarios
$usuarios    = new ColumnFamily($basedatos, 'usuarios');
 
//Crear un usuario
$usuarios->insert('6', array('name' => 'Juan Belon',
 'nick' => 'juaxix' ));
 
//Obtener usuario
$usuario = $usuarios->get('6');

 

Ok, hasta ahí para las bases de datos por columnas, como véis es bastante sencillo, de hecho hay algunas implementaciones por ejemplo para MongoDB que usan JSON para comunicarse con las API’s e incluso han creado fáciles administradores en PHP…,ahora,  para el caso de usar una base de datos distribuida orientada a almacenar documentos, sin ningún esquema, donde tienes un “cubo” de pares de llaves/valor dentro de un objeto, es uno de los casos en los que se puede usar un lenguaje más conocido por nosotros amantes del SQL, y MongoDB es lo que a los programadores PHP puede que les guste más porque se pueden escribir líneas de código tales como

$post -> where ( ‘id’  , $id ),

y cosas así, muy parecidas al modelo de datos persistentes de Google App Engine, de hecho hay bastantes implementaciones y herramientas para MongoDB ,supongo que porque es el tipo de base de datos NoSQL más divertida XD …hay un caso para usar con el framework y cms CakePHP, CodeIgniter, Symfony, etc, …veamos un ejemplo con ActiveMongo:

ActiveMongo::connect('mi-bd-twitter', 'localhost');
class Usuario extends ActiveMongo {
 public $nombre;
 public $usuario;
}
 
$usuario = new User();
$usuario->nombre = 'Juan Belon';
$usuario->usuario = 'juaxix';
 
//Insertar usuario
$usuario->save(); // XD qué fácil es ,eh
 
//Actualizar el nombre
$usuario->nombre = 'Juan Belon Perez';
$usuario->save();

así que sería fácil montar un sistema de bibliotecas para almacenar millones de entradas, en el caso de usar CouchDB, echadle un vistazo al link de herramientas de CouchDB con PHP, veréis que es muy parecido y la diferencia radica en que ésta tiene replicación bi-lateral (maestro-maestro) y una API JSON por defecto (en MongoDB es una extensión)…

En el caso en que te decidas por usar una base de datos distribuida basada en grafos (modelo de grafos construído con nodos con propiedades y relaciones ), tienes Neoj4por ejemplo que es totalmente transaccional y tiene una API muy flexible, pero es un poco más complejo de entender y puede que no la entiendas a la primera jeje pero úsala siempre que quieras establecer grafos de relaciones sociales, mapas de carreteras, topologías de red, etc. En PHP tienes NeojPHP, REST API, Thrift, etc. pero como digo, es algo más complejo y menos divertido.

¿Qué base de datos NoSQL usarás para crear tu clon de twitter ahora que sabes todo esto?

Otras Arquitecturas y metodologías SOA, ejercicios

Para terminar con las Arquitecturas Web vamos a dejar que Pablo García Sánchez nos cuente qué otras hay además de las que hemos visto: Otras Arquitecturas y metodologías SOA

EJERCICIO SIMPLE

  • Realizar un servicio web en Java con las operaciones:
    String addUser(String user, String pass) que la guarde en una lista (variable de clase) y devuelva un mensaje diciendo que se ha guardado
    boolean loginUser(String user, String pass) que compruebe que el usuario existe recorriendo la lista
    – (podemos usar dos listas de strings, HashMaps o crear una clase Usuario y guardarla en una List<Usuario>)
    – Testearlo en el navegador
  • Descargar ejercicio simple

EJERCICIO AVANZADO

  • Desarrollar dos servicios web (cada uno con su WSDL separado) utilizando JAX-WS. El primero debe recibir un XML con datos de un usuario <nombre><edad><contraseña><tel> y parsear ese XML con JDOM comprobando si hay  excepciones y guardarlo en una base de datos.
  • El segundo debe recibir un usuario y contraseña y devolver true si existe el usuario en la base de datos.
  • Finalmente crear un proceso BPEL con dos operaciones
    – Crear usuario (que ataque al primer servicio)
    – Hacer Login (que ataque al segundo) y devuelva un mensaje diciendo si los datos son correctos o no
    – Capturar Excepciones

EJERCICIO BPEL AVANZADO: descargar

fin Del Curso amigos

« Volver al Curso de Arquitectura de Servicios Web con Java y PHP

BPEL y OpenESB: Orquestación de Servicios Web

Introducción a BPEL y OpenESB

Normalmente integrar este tipo de servicios en multinacionales tiene un coste realmente alto, gracias a las herramientas que vemos en este curso se hace mucho más fácil la tarea.

La siguiente presentación de la mano de Pablo García Sánchez nos da las nociones básicas de ESB y JBI, para la integración empresarial de aplicaciones compuestas que generan un flujo de trabajo dinámico, además de dar algunas ventajas, vocabulario, y ejemplos de BPEL.

Necesitamos descargar los componentes ESB para nuestro servidor Glassfish así como para el IDE Netbeans, aunque os recomiendo el Java EE 5 Tools Bundle Installer y java ee sdk 6 preview ya que trae soporte para SOA para Glassfish y Netbeans 6.5.1 con todos los módulos instalados para trabajar con BPEL.

Veamos un ejemplo práctico con servicios web en vídeo:

Lo que hago es crear un nuevo proyecto tipo BPEL Module (recordar no crear un proyecto en un directorio con acentos), añadir un WSDL Externo desde
http://webservices.daehosting.com/services/TemperatureConversions.wso?WSDL
y un nuevo BPEL Process, para la entrada del BPEL creamos un WSDL local con un parámetro, la entrada de temperatura y un parámetro de salida que es la respuesta.

Por último existe un tutorial de BPEL disponible aquí.

« Volver al Curso de Servicios Web

Curso de PHP y servicios Web

Gracias a Pedro A. Castillo Valdivieso disponemos de este Curso de PHP:

Lo interesante, ahora que sabemos como programar servicios web complejos con Java y comunicarlos mediante SOAP es usar la clase que traen las últimas versiones de PHP (desde la 5.x), con un ejemplo sencillo, podemos probar a crear una lista de servicios como los que hay en http://www.service-repository.com/schema/namespaces …

El código sería tan sencillo como lo siguiente:

$wsdl = "http://www.currencyserver.de/webservice/currencyserverwebservice.asmx?WSDL";
echo "Servicios ofertados por <strong>$wsdl</strong>";
$client = new SoapClient($wsdl);
$avail = $client->__getFunctions();
echo '<ul></ul><ul>'; 
foreach($avail as $func) { 
echo "<li>" . $func . "</li></ul>"; } echo '<hr />'; 
echo highlight_string( file_get_contents(__FILE__));

Que devuelve una lista de las operaciones del servicio especificadas por el WSDL.

Y para terminar ya sabéis que podéis crear vuestros propios servicios web con PHP, un ejemplo sencillo:

//Añadiendo función suma:
$cliente = new SoapClient(
null,
array(
"location"=>"http://localhost/simple/serversimple.php",
"uri"=>""
)
);
$suma = $cliente->suma(2,3);
print("La suma de 2 y 3 es :".$suma);

Código fuente de serversimple.php:

function suma($a,$b){
  return intval($a)+intval($b);
}
$server = new SoapServer(null, array('uri'=>""));//Sin WSDL -> uri es obligatorio
$server->addFunction("suma");
$server->handle();

Ver ejemplo funcionando: aquí

Recordar que hay que generar los ficheros WSDL con Katy u otra herramienta.

« Volver al Curso de Servicios Web

Servicios web y Cloud Computing con JAVA, SOAP y PHP

DONDE ESTAMOS

Nos encontramos en un punto en el curso de Arquitectura de servicios web en el que ya hemos construido el modelo de datos que nos sirve como borrador para gestionar toda la información que ofertan los servidores y que los clientes tratan, así como de manipular esta información gracias a los servicios web que sirven de interfaces para dicha tarea.

¿QUÉ VAMOS A HACER?

Ahora vamos a centrarnos en la composición de servicios web para obtener un funcionamiento complejo mediante la invocación de estos servicios, concretamente a sus operaciones para construir un flujo de trabajo en nuestros servidores.

INTRODUCCIÓN

El nuevo modelo de datos basado en el que vimos en la lección anterior ( creación de servicios web con netbeans y glassfish ) para hacer las primeras pruebas con servicios web está diseñado para crear automáticamente pilotos y naves en un universo, de modo que se ha suprimido el usuario y se han añadido una clase Universo y una clase Galaxia para simular una pelea entre Vippers asociados a ella dentro de una clase EstrellaDeCombate. Dentro de Universo se encuentran todas las Galaxias y las estrellas de combate están dentro de éstas. Recordar que los vipers necesitan pilotos para volar y estos pilotos pueden estar o no activos.

¿CÓMO LO VAMOS A HACER?

Envolviendo el modelo de datos en una capa de integración de servicios web lo primero, así podemos crear una estrella de combate y prepararla para que que se pueda enfrentar a otra, lanzando las naves al combate, para después conocer su estado tras el enfrentamiento.

COMENZAMOS

  1. Crear un nuevo proyecto Java Web llamado “BattleStarGallacticaWebServer”, y dentro de este creamos un nuevo paquete (Java package) llamado
    es.ugr.cursows.battlestar.service
    Como era de esperar necesitamos añadir a las librerías el JAR del modelo de datos (código fuente y documentación ,también está la documentación online):  BSGModelo Universo.JAR.
  2. Para no hacer demasiado extenso este guión, uso esta presentación:

Lo importante de esta lección es aprender a crear servicios web y comunicarlos para ofrecer Servicios de Cloud Computing

Según esta empresa, esto es CloudComputing:

Y algo más sobre Cloud Computing : Cloud Sharing:

Las posibilidades se van haciendo cada vez mayores…el futuro de la evolución de la web pasa por aquí…

« Volver al Curso de Servicios Web | Ir a la siguiente lección »

Creación de un paquete de servicios web para un modelo de datos JAVA

Una vez creado nuestro paquete con la aplicación Java para interactuar con los servicios web como hemos visto en la lección anterior, vamos a realizar las tareas que habíamos dicho paso por paso. Es decir, vamos a crear un servicio web con una operación para añadir un usuario con su nombre de usuario, password, un nombre de piloto y una nave con su cantidad de armamento, otro para obtener una lista de usuarios con pilotos y naves y otro para hacer un login con usuario y password, para ello:

CREAR DIRECTORIO DE XML:

  1. Dentro de las propiedades del Proyecto Java Web “Excalibur” en la categoría de Sources  -> Package Folder -> Add Folder -> creamos el directorio “XML” dentro de “src” y de etiqueta (label) ponemos “XML”. Aquí vamos a colocar nuestros ficheros WSDL para ver como se construyen servicios web a partir de estos, pero primero el método sencillo…ahora se puede añadir al esquema de forma gráfica cualquier dato y se formatea por el sistema ,podemos crear un servicio web a partir del fichero…

CREAR SERVICIO WEB

  1. En el paquete “es.ugr.battlegalactica.servicios” -> botón derecho  -> New -> Web services -> Web Service -> “construccionNexus”. Añadir el constructor de la clase y la variable estática Nexus nexus de ésta clase, que se incializa en dicho constructor…

CREAR OPERACIÓN PARA AÑADIR UN USUARIO CON SUS PILOTOS Y SUS NAVES ASOCIADAS

  1. Segundo botón en el código dentro de la clase “construccionNexus” -> “Insert Code…” -> “Add Web Service Operation” -> le llamamos “crearUsuarioConPilotosYnaves”
  2. En return type (tipos devueltos) ponemos java.lang.Long y así, si es -1 ha ocurrido un error y en otro caso es el ID del nuevo usuario
  3. Para los parámetros necesitamos que tenga: un nombre y password de usuario,un nombre de piloto  y un nombre de nave; por lo que empezamos por añadir el primer campo con name: “datos_usuario” , type: Choose -> find type -> buscamos “usuario” y seleccionamos el del modelo de datos de BSGModelo, ahora hacemos lo propio para “datos_piloto” -> Piloto y “datos_nave” -> Viper. Pinchamos en “OK” y se genera el código en Java, sólo hemos de meter los datos correspondientes que nos pasa tan amablemente el servicio web a la base de datos de Nexus ,tal como hacíamos en Prueba.java…
    la función de la operación debe quedar así:

    @WebMethod(operationName = "crearUsuarioConPilotosYnaves")
    public Long crearUsuarioConPilotosYnaves(@WebParam(name = "datos_usuario")
    Usuario datos_usuario, @WebParam(name = "datos_piloto")
    Piloto datos_piloto, @WebParam(name = "datos_nave")
    Viper datos_nave) {
     
    if (nexus.obtenerUsuario(datos_usuario.getUsuario())!=null ){
    //El usuario ya existe, salir!
    return new Long(-1);
    }
     
    //Añadir Viper
    Viper v  = null;
    try { //Buscar viper:
    v = nexus.obtenerViper(datos_nave.getNombre());
    } catch (ViperNoEncontradoException ex){
    //La nave no existe, la añadimos
    v = new Viper(datos_nave.getNombre());
    v.setArmamento(datos_nave.getArmamento());
    } finally {
    //En otro caso, la nave es la misma?
    if (!v.getId().equals(datos_nave.getId())){
    //No es la misma, error
    return new Long(-1);
    }
    }
     
    //Añadir piloto:
    Piloto p = null;
    try {
    p = nexus.obtenerPiloto(datos_piloto.getId());
    } catch (PilotoNoEncontradoException ex){
    //NO Existe el piloto, crearlo
    p = new Piloto(datos_piloto.getNombre(), datos_piloto.getDestreza(),
    v.getId());
    nexus.guardarPiloto(p);
    } finally {
    //El piloto existe, tiene la misma ID?
    if (!p.getId().equals(datos_piloto.getId())){
    return new Long(-1);
    }
    }
    ArrayList<Long> lista_pilotos = new ArrayList<Long>();
    lista_pilotos.add(p.getId());
     
    //Añadir el usuario con los datos almacenados ya en Nexus:
    Usuario u = new Usuario(
    datos_usuario.getUsuario(),
    datos_usuario.getPassword(),
    lista_pilotos );
     
    nexus.guardarUsuario(u);
     
    return u.getId();
    }

    Para probarla primero hacemos click con el segundo botón del ratón en el proyecto Excalibur > Deploy ,esto instalará la aplicación web con la nueva operación compilada, ahora vamos a la lista de servicios web y pulsamos en test Web Service, ya podemos añadir usuarios con un piloto y una nave

CREAR OPERACIÓN PARA HACER UN LOGIN CON USUARIO Y PASSWORD

  1. Una vez creado un usuario en la base de datos la función para hacer un login es tan simple como esta:
    @WebMethod(operationName = "hacerLogin")
    public String operation(@WebParam(name = "usuario")
    String nombre_usuario, @WebParam(name ="password") String contrasena) {
    //TODO write your implementation code here:
    Usuario u = nexus.obtenerUsuario(nombre_usuario);
    if (u==null) return "El usuario no existe";
    else if (u.getPassword().equals(contrasena)){
    return "Acceso concedido";
    } else {
    return "Contraseña inválida";
    }
    }

    Recordar que para testear los servicios podemos hacerlo en SOAP UI:

CREAR OPERACIÓN PARA OBTENER UN LISTADO DE USUARIOS

  1. Es simplemente crear un listado a partir de recorrer el array de estos y devolverlo para que lo analice sintácticamente el sistema y devuelva la construcción XML correspondiente:
    public List<Usuario> listadoUsuarios() {
    List<Usuario> listado = null;
    for (Iterator<Usuario> iter = nexus.listarUsuarios(); iter.hasNext(); ){
    listado.add(iter.next());
    }
    return listado;
    }

Buenas prácticas de programación: Los servicios web son un tipo de comunicación, añadir lógica de programación resulta en algo no-generalizable y por lo tanto ,no reutilizable. Resumiento: hay que hacer una conversión de los datos de un modelo de datos en un modelo de datos de un servicio web,i.e.,las clases con su lógica de programación en Java a un modelo del servicio y luego el paso inverso. Entre medias están las páginas web u otros clientes que los utilizan con su propia lógica. Por ello se recomienda diseñar los servicios web lo último, cuando ya tenemos todo lo que necesitamos en cuanto a datos y lógica interna con ellos, separar cada fichero WSDL para cada servicio es recomendable por si necesitamos cambiar algo y nos cuesta menos trabajo.

CREAR CLIENTES PARA CONECTARSE A LOS SERVICIOS WEB

  1. En el proyecto “Excalibur” creamos el paquete “es.ugr.battlegalactica.servicios” y dentro de este -> segundo botón del ratón-> New -> Other -> Web Services -> Web Service Client -> seleccionamos del proyecto “Excalibur” el Servicio Web “construccionNexus” -> OK ; y ahora en package ponemos “es.ugr.battlegalactica.clientes”. Esto debe crearnos todas las clases Java para comunicarse con las operaciones del Servicio Web. Pero para saber que funcionan usamos un JUnit Test , creamos un paquete llamado “es.ugr.battlegalactica.clientes” y dentro un nuevo JUnit Test para clases existentes, elegimos la clase a testear y hacemos como en la primera lección las unidades de prueba.

< Volver al curso de Arquitectura de Servicios Web con JAVA y PHP

Página 1 de 212
footer
jbelon © | sitemap.xml