Registro de Web Services con Apache jUDDI. Configuración y ejemplo
Introducción
En este tutorial vamos a tratar uno de los aspectos que menos partido se sacan en el contexto de los web services: su catalogación y búsqueda en servidores de registro, bajo la especificación UDDI (Universal Description, Discovery and Integration), uno de los pilares básicos junto con XML, WSDL y SOAP.
Veamos un ejemplo introductorio a la catalogación de servicios (y su posterior búsqueda) utilizando herramientas opensource. Cabe decir que los servidores empresariales propietarios incluyen estas y numerosas más características sobre las que, si queremos aplicar a nuestra empresa, deberemos profundizar.
Instalación de Apache jUDDI
Requisitos
El software utilizado en este tutorial es:
- Apache jUDDI versión 2.0rc6, que podemos descargar desde http://ws.apache.org/juddi/releases.html. Escogemos la distribución ya integrada con Tomcat 5.5: juddi-tomcat-2.0rc6.zip
- MySQL Server 5.1 versión Windows MSI Installer (x86), disponible en: http://dev.mysql.com/downloads/mysql/5.1.html#win32
- MySQL GUI Tools versión Windows (x86): http://dev.mysql.com/downloads/gui-tools/5.0.html (opcional pero recomendable para ejecutar los scripts DDL y DML)
- Sun Java JDK 1.5.0_*, que podemos descargar desde http://java.sun.com/javase/downloads/index_jdk5.jsp, y correctamente configurado
- UDDI Browser 0.2 beta, distribución UDDI Browser Binaries, disponible en la web del proyecto: http://uddibrowser.org/
La plataforma de ejecución está basada en:
- Pc portátil C2Duo, 1.5GHz, 3GB Ram
- Windows Vista Home Premium SP1
Con las versiones antes indicadas se asegura el correcto funcionamiento de este tutorial.
Paso 1. Instalar el servidor Apache Tomcat
Descomprimir el fichero juddi-tomcat-2.0rc6.zip que hemos descargado, en un directorio a nuestra elección. Al ser un Tomcat el servidor sobre el que se ejecuta jUDDI, establecemos la variable del sistema CATALINA_HOME. En el caso de este tutorial, CATALINA_HOME=C:\Tutoriales\juddi\apache-tomcat-5.5.23
Paso 2. Integrar jUDDI con MySQL
jUDDI hace uso de una base de datos relacional en la que almacena los metadatos de los web services que maneja. Viene preparado para 14 bases de datos (por defecto Apache Derby); nosotros vamos a configurar MySQL.
Paso 2.1. Instalar el driver JDBC de MySQL
Necesitamos Connector/J 5.1, el driver JDBC oficial de MySQL para Java. Accedemos a http://dev.mysql.com/downloads/connector/j/5.1.html, descargamos la distribución Source and Binaries (zip), lo descomprimimos y copiamos el ensamblado mysql-connector-java-5.1.7-bin.jar en CATALINA_HOME\common\lib
Paso 2.2. Preparar la base de datos
Creamos un esquema y un usuario con permisos sobre el mismo para la posterior creación de las tablas:
- Esquema: juddidb
- Usuario: juddi_user
- Contraseña: juddi_pwd
Podemos hacerlo desde una intergaz gráfica (e.g. MySQL GUI Tools) o mediante las sentencias bajo consola mysql y usuario administrador (e.g. root):
CREATE DATABASE `juddidb` DEFAULT CHARACTER SET utf8; GRANT ALL ON juddidb.* TO 'juddi_user' IDENTIFIED BY 'juddi_pwd';
A continuación ejecutamos sobre el esquema juddidb los siguientes scripts, que crean y pueblan las tablas con datos:
- create_database.sql
- insert_publishers.sql
NOTA: estos scripts son los propios que se distribuyen con jUDDI (véase CATALINA_HOME\webapps\juddi\WEB-INF\lib\juddi-2.0rc6.jar\juddi-sql\mysql\create_database.sql y CATALINA_HOME\webapps\juddi\WEB-INF\lib\juddi-2.0rc6.jar\juddi-sql\insert_publishers.sql), pero con ciertas modificaciones:
- El create_database.sql original de jUDDI 2.0rc6 incluye una función de tiempo errónea (no sólo en Derby, también en MySQL) en una de las sentencias, lo cual provoca que el proceso falle (http://issues.apache.org/jira/browse/JUDDI-184). Se ha corregido este error.
- Se ha eliminado el prefijo de las tablas
- Se ha cambiado los datos del publisher original de insert_publishers.sql por:
INSERT INTO PUBLISHER (PUBLISHER_ID,PUBLISHER_NAME,EMAIL_ADDRESS,IS_ENABLED,IS_ADMIN, MAX_BUSINESSES,MAX_SERVICES_PER_BUSINESS,MAX_BINDINGS_PER_SERVICE,MAX_TMODELS) VALUES ('autentia','Autentia SL','igpuebla@autentia.com','true','true',25,20,10,100);
Paso 3. Configurar jUDDI
Editamos en primer lugar el fichero de configuración CATALINA_HOME\webapps\juddi\WEB-INF\juddi.properties. Modificamos las líneas necesarias para que queden como se muestra a continuación:
# The UDDI Operator Name juddi.operatorName = autentia # The i18n locale default codes juddi.i18n.languageCode = es juddi.i18n.countryCode = ES # The UDDI Operator Contact Email Address juddi.operatorEmailAddress = igpuebla@autentia.com # straight JDBC juddi.jdbcDriver=com.mysql.jdbc.Driver juddi.jdbcUrl=jdbc:mysql://localhost:3306/juddidb?autoReconnect=true juddi.jdbcUsername=juddi_user juddi.jdbcPassword=juddi_pwd # jUDDI database creation juddi.isCreateDatabase=false #juddi.tablePrefix=JUDDI_ juddi.databaseExistsSql=select * from ${prefix}BUSINESS_ENTITY juddi.sqlFiles=juddi-sql/derby/create_database.sql,juddi-sql/insert_publishers.sql
Sólo indicar que no permitimos que jUDDI cree automáticamente las tablas en su primera ejecución (juddi.isCreateDatabase=false) porque el proceso falla (nota del paso 2.2).
Modificamos a continuación el fichero CATALINA_HOME\conf\Catalina\localhost\juddi.xml y cambiamos la etiqueta Resource por el siguiente fragmento:
<Resource name="jdbc/juddiDB"
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
username="juddi_user"
password="juddi_pwd"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/juddidb?autoReconnect=true"
> </Resource>
Editamos ahora CATALINA_HOME\conf\server.xml y añadimos las siguientes definiciones en la sección <Host></Host>:
<Context path="/juddi"
docBase="juddi"
debug="5"
reloadable="true"
crossContext="true"
> <Logger className="org.apache.catalina.logger.FileLogger"
prefix="localhost_juddiDB_log"
suffix=".txt"
timestamp="true"
/> <Resource name="jdbc/juddiDB"
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
username="juddi_user"
password="juddi_pwd"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/juddidb?autoReconnect=true"
> </Resource> </Context>
Ya tenemos preparado el servidor para su uso. Vamos a comprobarlo.
Paso 4. Probar jUDDI
Arrancamos el servidor con CATALINA_HOME\bin\startup.bat. Ni en la pantalla de log de Tomcat ni en CATALINA_HOME\logs\*.log habrá ninguna traza de error.
Accedemos a http://localhost:8080/juddi y nos recibirá la siguiente pantalla:
Pantalla de bienvenida de Apache jUDDI
Podemos validar la instalación pulsando en el enlace Validate. Ante cualquier aviso de error, deberemos revisar los pasos explicados anteriormente:
Pantalla de validación de la instalación e información de jUDDI
Todo parece funcionar correctamente.
Catalogar Web Services con jUDDI Console
Apache jUDDI facilita una consola para operar directamente con su API mediante mensajes SOAP. Pulsamos en el enlace jUDDI Console y se nos mostrarán otros tantos para invocaciones individuales a los métodos. Cabe destacar que jUDDI ofrece algunos métodos que se salen del estándar UDDI 2.0.
Pantalla de jUDDI Console, con enlaces a los métodos de la API
Vamos a dar de alta el servicio de consulta de tiempo meteorológico, cuya descripción de interfaz la encontramos en http://www.webservicex.net/globalweather.asmx?wsdl
Paso 1. Autenticarse contra jUDDI
Debemos obtener el token de autorización que usaremos para el resto de operaciones. Para ello accedemos al método de la API de publicación: get_authToken y componemos el siguiente mensaje SOAP de invocación (sustituimos los *** por nuestros valores):
<?xml version="1.0"
encoding="utf-8"
?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
> <soapenv:Body> <get_authToken generic="2.0"
xmlns="urn:uddi-org:api_v2"
userID="autentia"
cred=""
/> </soapenv:Body> </soapenv:Envelope>
Pulsamos Submit y recibimos el token de autenticación ante el servidor en otro mensaje SOAP:
<?xml version="1.0"
encoding="UTF-8"
?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
> <soapenv:Body xmlns="urn:uddi-org:api_v2"
> <authToken generic="2.0"
operator="autentia"
> <authInfo>authToken:3BC82C10-254C-11DE-BE07-C8B0C2480445</authInfo> </authToken> </soapenv:Body> </soapenv:Envelope>
En adelante nos identificaremos ante invocaciones a métodos de publicación con : authToken:3BC82C10-254C-11DE-BE07-C8B0C2480445
Paso 2. Publicar una entidad de negocio (White Pages)
Utilizamos el método dela API save_business para dar de alta una nueva businessEntity (entidad de negocio, i.e. información sobre quién está haciendo público qué servicios web. A este componente de UDDI se denomina White Pages) Completaremos el mensaje de la siguiente manera:
<?xml version="1.0"
encoding="utf-8"
?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
> <soapenv:Body> <save_business generic="2.0"
xmlns="urn:uddi-org:api_v2"
> <authInfo>authToken:3BC82C10-254C-11DE-BE07-C8B0C2480445</authInfo> <businessEntity businessKey=""
> <name>Autentia</name> <description>Soporte a Desarrollo Informatico</description> <contacts> <contact useType="Soporte"
> <personName>Ivan</personName> <phone>916753306</phone> <email>igpuebla@autentia.com</email> </contact> </contacts> </businessEntity> </save_business> </soapenv:Body> </soapenv:Envelope>
veremos que jUDDI confirma la operación con:
<?xml version="1.0"
encoding="UTF-8"
?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
> <soapenv:Body xmlns="urn:uddi-org:api_v2"
> <businessDetail generic="2.0"
operator="autentia"
> <businessEntity authorizedName="Autentia SL"
businessKey="403F4A60-254E-11DE-BE07-B4D4FA47ACC4"
operator="autentia"
> <discoveryURLs> <discoveryURL useType="businessEntity"
> http://localhost:8080/juddi/uddiget.jsp?businesskey=403F4A60-254E-11DE-BE07-B4D4FA47ACC4 </discoveryURL> </discoveryURLs> <name>Autentia</name> <description>Soporte a Desarrollo Informatico</description> <contacts> <contact useType="Soporte"
> <personName>Ivan</personName> <phone>916753306</phone> <email>igpuebla@autentia.com</email> </contact> </contacts> </businessEntity> </businessDetail> </soapenv:Body> </soapenv:Envelope>
Paso 3. Crear un tModel (Yellow Pages)
Un tModel es una estructura para almacenar metadatos (descripción, clasificación, localización…) sobre los servicios catalogados, orientado a facilitar las búsquedas. Accedemos al método de la API save_tModel y completamos según la siguiente información, teniendo en cuenta que debemos utilizar las siguientes constantes (definidas en la especificación):
- tModelKey: UUID:C1ACF26D-9672-4404-9D70-39B756E62AB4
- keyName: uddi-org:types
- keyValue: wsdlSpec
<?xml version="1.0"
encoding="utf-8"
?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
> <soapenv:Body> <save_tModel generic="2.0"
xmlns="urn:uddi-org:api_v2"
> <authInfo>authToken:3BC82C10-254C-11DE-BE07-C8B0C2480445</authInfo> <tModel tModelKey=""
> <name>http://www.webservicex.net/globalweather.asmx?wsdl</name> <description>Web Service para consulta del tiempo meteorologico. Publicado en la web de www.webservicex.net</description> <overviewDoc> <description>Web Service para consulta del tiempo meteorologico</description> <overviewURL>http://www.webservicex.net/globalweather.asmx?wsdl</overviewURL> </overviewDoc> <identifierBag> <keyedReference tModelKey="***"
keyName="***"
keyValue="***"
/> </identifierBag> <categoryBag> <keyedReference tModelKey="UUID:C1ACF26D-9672-4404-9D70-39B756E62AB4"
keyName="uddi-org:types"
keyValue="wsdlSpec"
/> </categoryBag> </tModel> </save_tModel> </soapenv:Body> </soapenv:Envelope>
respuesta:
<?xml version="1.0"
encoding="UTF-8"
?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
> <soapenv:Body xmlns="urn:uddi-org:api_v2"
> <tModelDetail generic="2.0"
operator="autentia"
> <tModel authorizedName="Autentia SL"
operator="autentia"
tModelKey="uuid:6F85E1B0-2550-11DE-BE07-DDAE5640FB05"
> <name>http://www.webservicex.net/globalweather.asmx?wsdl</name> <description>Web Service para consulta del tiempo meteorologico. Publicado en la web de www.webservicex.net</description> <overviewDoc> <description>Web Service para consulta del tiempo meteorologico</description> <overviewURL>http://www.webservicex.net/globalweather.asmx?wsdl</overviewURL> </overviewDoc> <identifierBag> <keyedReference keyName="***"
keyValue="***"
tModelKey="***"
/> </identifierBag> <categoryBag> <keyedReference keyName="uddi-org:types"
keyValue="wsdlSpec"
tModelKey="UUID:C1ACF26D-9672-4404-9D70-39B756E62AB4"
/> </categoryBag> </tModel> </tModelDetail> </soapenv:Body> </soapenv:Envelope>
Paso 4. Dar de alta el servicio y su localización (Green Pages)
Dicho brevemente, debemos proporcionar la información del servicio (businessService), y asociarlo con la localización del recurso (bindingTemplate). Con el businessKey y tModelKey de los pasos anteriores, compondremos el siguiente mensaje SOAP en el método de la API save_service:
<?xml version="1.0"
encoding="utf-8"
?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
> <soapenv:Body> <save_service generic="2.0"
xmlns="urn:uddie-org:api_v2"
> <authInfo>authToken:3BC82C10-254C-11DE-BE07-C8B0C2480445</authInfo> <businessService businessKey="403F4A60-254E-11DE-BE07-B4D4FA47ACC4"
serviceKey=""
> <name>Web Service para la consulta de tiempo meteorologico</name> <description>Dada una localidad valida, podemos obtener su nivel de viento, visibilidad, temperatura, humedad, presion atmosferica, etc.</description> <bindingTemplates> <bindingTemplate bindingKey=""
> <accessPoint URLType="http"
>http://www.webservicex.net/globalweather.asmx</accessPoint> <tModelInstanceDetails> <tModelInstanceInfo tModelKey="UUID:C1ACF26D-9672-4404-9D70-39B756E62AB4"
> <instanceDetails> <overviewDoc> <overviewURL>http://www.webservicex.net/globalweather.asmx?wsdl</overviewURL> </overviewDoc> </instanceDetails> </tModelInstanceInfo> </tModelInstanceDetails> </bindingTemplate> </bindingTemplates> </businessService> </save_service> </soapenv:Body> </soapenv:Envelope>
mensaje SOAP de respuesta:
<?xml version="1.0"
encoding="UTF-8"
?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
> <soapenv:Body xmlns="urn:uddi-org:api_v2"
> <serviceDetail generic="2.0"
operator="autentia"
> <businessService businessKey="403F4A60-254E-11DE-BE07-B4D4FA47ACC4"
serviceKey="7E006F70-2551-11DE-BE07-C23E97D2B96C"
> <name>Web Service para la consulta de tiempo meteorologico</name> <description>Dada una localidad valida, podemos obtener su nivel de viento, visibilidad, temperatura, humedad, presion atmosferica, etc.</description> <bindingTemplates> <bindingTemplate bindingKey="7E1CF820-2551-11DE-BE07-A915F4C03D90"
serviceKey="7E006F70-2551-11DE-BE07-C23E97D2B96C"
> <accessPoint URLType="http"
>http://www.webservicex.net/globalweather.asmx</accessPoint> <tModelInstanceDetails> <tModelInstanceInfo tModelKey="UUID:C1ACF26D-9672-4404-9D70-39B756E62AB4"
> <instanceDetails> <overviewDoc> <overviewURL>http://www.webservicex.net/globalweather.asmx?wsdl</overviewURL> </overviewDoc> </instanceDetails> </tModelInstanceInfo> </tModelInstanceDetails> </bindingTemplate> </bindingTemplates> </businessService> </serviceDetail> </soapenv:Body> </soapenv:Envelope>
Ya tenemos nuestro web service registrado para que potenciales clientes puedan buscar, dar con él y acceder a su WSDL.
Realizar todos estos pasos a mano es bastante engorroso, pero nos da una idea del cómo y porqué de UDDI. Podemos automatizarlo programáticamente, o bien mediante alguna herramienta con capacidades desarrolladas al efecto. Vamos a trabajar con UDDI Browser.
Catálogo y consulta mediante aplicación cliente: UDDI Browser 0.2
UDDI Browser es un desarrollo opensource de Alex Holmes, y soporta la UDDI 2.0. Está configurado para trabajar out-of-the-box con los registros públicos de IBM, Microsoft, SAP, HP… (algunos de ellos ya no están disponibles). Nosotros añadiremos un nuevo registro: nuestro jUDDI.
Instalación
La distribución UDDI Browser Binaries será el fichero comprimido ub-0.2-bin.zip. Lo descomprimimos en una carpeta, e iniciamos la aplicación con ub-0.2-bin\bin\ub.bat:
UDDI Browser 0.2
Añadir nuevo registro UDDI
Accedemos al menú Edit | UDDI Registries, donde veremos los que incorpora el browser por defecto. Podemos probar con algunos de ellos (y ver en la consola las trazas que aparecen). Vamos a añadir nuestro nuevo servidor. Para ello pulsamos en Add y completamos el formulario:
- Name: el nombre que queramos, e.g. Tutorial jUDDI
- Inquiry URL: http://localhost:8080/juddi/inquiry
- Publish URL: http://localhost:8080/juddi/publish
- Username: autentia
- Password: (ninguna)
Aceptamos con Ok. Nos situamos sobre la nueva entrada y pulsamos en Connect:
Alta de la conexión Tutorial jUDDI
Alta de servicios
Daremos en primer lugar de alta una entidad de negocio, Adictosaltrabajo, en Edit | Add Business…
Aceptamos la operación pulsando Add, y el servidor nos responde con la businessKey asociada:
businessKey para nuestro nuevo negocio registrado
Esta entidad de negocio tendrá asociado el publisher que dimos de alta en la instalación de jUDDI (Autentia SL). Vamos a dar de alta un servicio que convierte texto a Braille: http://www.webservicex.net/WCF/ServiceDetails.aspx?SID=41. Sobre la entidad, hacemos botón derecho y pulsamos sobre Add Service (vemos que a la entidad de negocio pueden añadírsele más datos):
En el diálogo introducimos un nombre de web service: Conversor a Braille:
Nombre del servicio
pulsamos sobre Add, y obtendremos como respuesta la serviceKey:
serviceKey del servicio
Como último paso vamos a agregar la localización del web service, agregando un bindingTemplate. Botón derecho sobre nuestro nuevo servicio y seleccionamos Add Binding Template for Access Point:
completamos el formulario:
- Access Point Text:
http://www.webservicex.net/braille.asmx - Access Point URL Type:
http - tModelKey: UUID:C1ACF26D-9672-4404-9D70-39B756E62AB4
Aceptamos con Ok y veremos que ha creado una bindingTemplate con un tModel. Ya tenemos nuestro servicio publicado:
Servicio de conversión a texto Braille publicado
Consulta de servicios
Podemos realizar búsquedas en el registro de múltiples maneras. Si hemos seguido el tutorial y hemos incluido el servicio meteorológico, vamos a buscarlo:
- Búsqueda simple. Menú View | Basic Find, y ponemos como Business (empresa, negocio), Autentia:
Diálogo de búsqueda simple
Obtendremos como resultado nuestra entidad de negocio, de la cual podremos obtener sus servicios y descripciones, desplegando el árbol:
Entidad Autentia, con el servicio web asociado en el registro
- Búsqueda avanzada: Menú View | Advanced Find, y podemos incluir varios criterios de búsqueda.
- Solicitar un listado de todos los elementos disponibles: Businesses, Services o tModels. Menú View | Find More | Find all services, por ejemplo:
Servicios registrados en nuestro servidor UDDI
Conclusiones
Este tutorial resulta extenso, si bien cubre varios aspectos interesantes acerca del registro de web services:
- Una breve visión de la especificación de descubrimiento UDDI
- Las entidades básicas que intervienen a la hora de registrar un servicio: Business, Service, tModel
- Capacidad para crear nuestro propio registro de web services (+)
- Posibilidad de consultar registros públicos mediante herramientas clientes (+)
Para ello hemos utilizado un servidor y cliente quizás poco maduros en su desarrollo y con algunas limitaciones (no soportan UDDI V3), pero lo suficientemente estables para los propósitos de este tutorial.
Muchas gracias, excelente material, de primera diría yo. Siguiendo las instrucciones pude utilizar DB2 como repositorio.
Muchas gracias, excelente Tutorial.
Oye una pregunta ¿Sabes Como puedo hacer el registro la búsqueda y selección de los servicios a través de un cliente en Netbeans?