<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>AQuA.it &#187; Arquitectura</title>
	<atom:link href="http://blog.aquait.info/category/arquitectura/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.aquait.info</link>
	<description>Blog técnico de AQuA.it</description>
	<lastBuildDate>Mon, 17 Oct 2011 12:15:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>JBoss AS 7- Primera parte: Trucos nuevos de un perro viejo</title>
		<link>http://blog.aquait.info/2011/08/jboss-as-7-primera-parte-trucos-nuevos-de-un-perro-viejo/</link>
		<comments>http://blog.aquait.info/2011/08/jboss-as-7-primera-parte-trucos-nuevos-de-un-perro-viejo/#comments</comments>
		<pubDate>Fri, 12 Aug 2011 20:48:09 +0000</pubDate>
		<dc:creator>Alejandro</dc:creator>
				<category><![CDATA[AppServer]]></category>
		<category><![CDATA[Arquitectura]]></category>
		<category><![CDATA[JBoss AS]]></category>
		<category><![CDATA[JBoss]]></category>

		<guid isPermaLink="false">http://blog.aquait.info/?p=261</guid>
		<description><![CDATA[Hace muy poco que RedHat liberó la versión 7 de su servidor de aplicaciones.  Con esta nueva versión nos muestra como una empresa grande es capaz de lanzar un producto &#8220;viejo&#8221; totalmente renovado adecuado a las necesidades actuales. Esta versión no solo soporta Java EE6 sino que también plantea un cambio drástico en la arquitectura [...]]]></description>
			<content:encoded><![CDATA[<p>Hace muy poco que RedHat liberó la versión 7 de su servidor de aplicaciones.  Con esta nueva versión nos muestra como una empresa grande es capaz de lanzar un producto &#8220;viejo&#8221; totalmente renovado adecuado a las necesidades actuales. Esta versión no solo soporta Java EE6 sino que también plantea un cambio drástico en la arquitectura del servidor de aplicaciones.  Nuestra intensión es sacar una serie de artículos mostrando cuales son los cambios introducidos. Estos no intentan ser una guía completa sobre JBoss 7 sino más bien un vistazo general para que ustedes puedan aprender junto con nosotros que se trae esta nueva versión. Les aclaramos que la  información presentada en estos artículos está tomada en parte de la propia documentación de JBoss, de algunos comentarios del foro de JBoss y de nuestra &#8220;experimentação&#8221;.<br />
Ahora basta de cháchara y arranquemos.</p>
<p><span id="more-261"></span><strong>Primero lo primero &#8211; Instalando el JBoss AS 7</strong></p>
<p>Cuando vayamos a <a title="Home JBoss" href="www.jboss.org" target="_blank">www.jboss.org</a> veremos que por primera vez existen dos versiones del servidor para bajarnos.</p>
<ul>
<li> Web Profile Only (Java EE6 Certfied)</li>
<li> Everthing (NOT Java EE6 Certfied)</li>
</ul>
<p>La primera como su nombre lo indica está orientada al la ejecución de aplicaciones Web y como se puede apreciar es una configuración certificada en cumplir con todos los requerimientos de un servidor Java EE6 con web profile. La otra configuración es lo que se conoce por Full profile pero que todavía no ha sido certificada y no soporta todos lo que necesita un servidor Full Profile,  por lo cual es llamada &#8220;Full preview profile&#8221;.<br />
Yendo a lo concreto, la diferencia entre el Web y el Full es básicamente es la siguiente</p>
<ul>
<li> JSR 914 &#8211; Soporte de JMS</li>
<li> JSR 224- Java API 2.2 para WebServices basados en XML (JAX-WS)</li>
</ul>
<p>Cualquiera de las configuraciones la podemos bajar desde la <a title="download JBoss AS 7" href="http://www.jboss.org/jbossas/downloads" target="_blank">página de download de JBoss</a>.<br />
Para los ejemplos acá planteados cualquiera de las dos es indistinta. Si no piensan usar JMS y WebServices entonces con la Web van a estar más que bien. Tengan en cuenta que ambas vienen con la variación Lite del contenedor de EJB especificado en la <a href="http://jcp.org/en/jsr/detail?id=318">JSR-381</a>. Este contenedor es una versión limitada la cual NO soporta:</p>
<ul>
<li> Remote interfaces</li>
<li> RMI-IIOP Interoperability</li>
<li> JAX-WS Web Service Endpoints</li>
<li> EJB Timer Service (@Schedule, @Timeout)</li>
<li> Asynchronous session bean invocations (@Asynchronous)</li>
<li> Message-driven beans</li>
</ul>
<p>Los que quieran ver un poco más sobre que soporta y que no cada una de las versiones pueden consultar la tabla que hay en la <a title="Guia JBoss AS 7" href="https://docs.jboss.org/author/display/AS7/Getting+Started+Guide">guía de JBoss</a></p>
<p><strong>Ahora a los bifes &#8211; Ejecutando el JBoss AS 7.0</strong><br />
Para ejecutar el servidor debemos tener descomprimido el archivo bajado  (el zip o el tar.gz) en una carpeta donde mejor nos quede. Por ejemplo en mi caso yo lo instale en <em>Users/ale/opt/Applications/jboss-as-web-7.0.0.Final</em>.<br />
El único requerimiento que tenemos es que debemos tener instalada una versión de la JDK que sea la 6 o superior.</p>
<p>Luego debemos abrir una terminal o consola, dependiendo del sistema en que estamos, y posicionarnos en la carpeta raíz donde instalamos el servidor.<br />
Ahí ponemos nuestro asiento en posición vertical, nos abrochamos los cinturones y ejecutaremos:</p>
<ul>
<li> bin\stanadalone.bat si es que estamos en windows</li>
<li> bin/stanadalone.sh si estamos en cualquier variante de Unix</li>
</ul>
<p>Paren las rotativas!!! ¿Que es esto de standalone?  Por  ahora para la comprensión de este artículo solo diremos que standalone es uno de los dos modos de ejecución que trae la versión 7. De las dos opciones esta es la más similar en su funcionamiento a las versiones anteriores de JBoss.</p>
<p>Ahora sí, levantemos el JBoss AS 7!!!. tecleamos <em>bin/stanadalone.sh [ENTER]</em><br />
Podemos ver como en muy pocos segundos ya está el JBoss AS 7 levantado!!! . Ahora sabemos de primera mano que esta nueva versión levanta con una velocidad mucho mayor que cualquiera de sus versiones anteriores. Eso no es por casualidad y se debe a su nuevo diseño el cual nos provee de un nuevo proceso de carga de componentes. Este proceso tiene dos grandes cambios:</p>
<ol>
<li> Carga concurrente de los servicios, aprovechando los múltiples procreadores que tengamos</li>
<li>Solo levanta los servicios críticos para el correcto funcionamiento del servidor. Cualquier otro servicio no crítico queda levantado en forma pasiva hasta que sea utilizado por primera vez.</li>
</ol>
<p>Según RedHat esta versión ofrece una reducción de 10 veces en el tiempo de arranque con respecto a las versiones anteriores.<br />
Esto podemos confirmar si miramos la última linea impresa por el JBoss, la cual debe decir algo así:</p>
<pre class="brush: shell">...
...
...
17:30:11,370 INFO  [org.jboss.as.jmx.JMXConnectorService] (MSC service thread 1-4) Starting remote JMX connector
17:30:11,405 INFO  [org.jboss.as.ee] (Controller Boot Thread) Activating EE subsystem
17:30:11,878 INFO  [org.jboss.as.remoting] (MSC service thread 1-3) Listening on /127.0.0.1:9999
17:30:12,049 INFO  [org.apache.coyote.http11.Http11Protocol] (MSC service thread 1-8) Starting Coyote HTTP/1.1 on http--127.0.0.1-8080
17:30:12,742 INFO  [org.jboss.as.connector] (MSC service thread 1-7) Starting JCA Subsystem (JBoss IronJacamar 1.0.0.CR2)
17:30:13,360 INFO  [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-4) Bound data source [java:jboss/datasources/ExampleDS]
17:30:14,120 INFO  [org.jboss.as.deployment] (MSC service thread 1-4) Started FileSystemDeploymentService for directory /Users/ale/opt/Applications/jboss-as-web-7.0.0.Final/standalone/deployments
17:30:14,132 INFO  [org.jboss.as] (Controller Boot Thread) JBoss AS 7.0.0.Final "Lightning" started in 7885ms - Started 92 of 147 services (55 services are passive or on-demand)</pre>
<p>En este caso podemos ver como en JBoss levanto en casi 8 segundos.</p>
<p>Para bajar el JBoss no hay misterios, hacemos como siempre hasta ahora <em>Ctrl+C</em>.</p>
<p><strong>Me parece que vi un lindo gatito &#8211; Nueva consola Web</strong><br />
Una vez que tenemos el servidor levantado pasemos a ver otra de las mejoras que trae que es su consola web de administración. Esta consola si la comparamos con la anterior es un avance importante en cuanto a la estética. La consola es una aplicación GWT lo cual la hacen mucho más rica en su funcionamiento. Dentro de esta podemos hacer varias actividades de administración, como ser:</p>
<ul>
<li> Configuración de los datasource</li>
<li> Configuración de los logs</li>
<li> Configuración de los conectores web y virtual host</li>
<li> Realizar  deployments con al posibilidad de, habilitar, deshabilitar, subir y eliminar aplicaciones</li>
<li> Configuración de los puertos</li>
</ul>
<p>Para conectarnos a esta nueva consola tenemos que abrir un browser e ingresar: <a title="consola web" href="http://localhost:9990/console" target="_blank">http://localhost:9990/console</a></p>
<p>Una funcionalidad que se ha eliminado es la consola JMX. Este cambio se debe a que con JMX no se podía dar soporte a la nueva administración de dominios (hablaremos de ella en otro artículo). Ahora la forma de administrar es usando el modo nativo de administración. Desde este modo podemos configurar y accederá a todas las propiedades de los servidores. JBoss viene con una extensión que hace de puente entre JMX y la API nativa y nos permite conectarnos con un cliente JMX como el <em>jconsole</em>. En mis pruebas lo que si pude detectar es que no estaban todas las funcionalidades presentes en la consola JMX.</p>
<p>La consola web no es la única forma de acceder a la interfaz nativa de administración. Tenemos estás cuatro opciones:</p>
<ul>
<li> La consola web que como vimos es limitada</li>
<li> Con un cliente de linea de comando, muy completo por cierto.</li>
<li> Una API java que se puede acceder directamente con java remoting</li>
<li> Una API REST-like para enviar comando por http</li>
</ul>
<p>De estas vale la pena mencionar que la CLI que trae está muy completa, por  ejemplo soporta auto completado. Para describir esta consola necesitaríamos una artículo entero. Los interesados pueden leer más sobre esta en <a title="JBoss AS 7 CLI" href="https://docs.jboss.org/author/display/AS7/Management+Clients" target="_blank">JBoss CLI</a></p>
<p><strong>A la carga &#8211; Haciendo nuestro primer deploy</strong><br />
Como ya mencionamos una forma de hacer deploy es por medio del uso de la consola web. Esta forma es muy simple por lo cual no nos vamos a detener en explicar. Lo que si vamos a ver es como hacer un deploy a la vieja usanza copiando el archivo en el directorio de deployment. Para variar esto también ha cambiado, yo estoy convencido de que luego de tantos años de manejar la misma estructura del servidor la gente de JBoss se aburrió y para hacer su trabajo más divertido nos cambio todo!!! Por suerte los cambios son para mejor.</p>
<p>Entonces, ¿Donde debemos copiar nuestra aplicación? Como tenemos levantado el JBoss en modo standalone debemos copiar el artefacto (jar, war o ear) al directorio standalone/deployments. Y listo nuestra aplicación queda levantada y funcionando.</p>
<p><strong>Resumiendo</strong></p>
<p>Los más importante que vimos en el artículo es:<br />
Que versiones están disponibles para bajar<br />
Como levantar el servidor en modo <em>standalone: bin/standalone.sh</em><br />
Conectarnos a la consola Web: <a title="JBoss console" href="http://localhost:9990/console" target="_blank">http://localhost:9990/console</a><br />
Hacer un deployment: Copiar nuestra aplicación a<em> standalone/deployments</em></p>
<p>Por último espero que hayan visto que esta nueva versión incluye una cantidad de cambios aparte del soporte a Java EE 6.</p>
<p><strong>Para la próxima</strong></p>
<p>En el próximo artículo veremos más sobre los deploy y revelaremos el misterioso <em>&#8220;Sandalone&#8221;</em>. Antes de despedirme les dejo un deber, ¿luego de hacer el deploy, no ven nada extraño en el directorio deployments?</p>
<p>Saludos y hasta la próxima.</p>
<p><a class="a2a_button_blogger_post" href="http://www.addtoany.com/add_to/blogger_post?linkurl=http%3A%2F%2Fblog.aquait.info%2F2011%2F08%2Fjboss-as-7-primera-parte-trucos-nuevos-de-un-perro-viejo%2F&amp;linkname=JBoss%20AS%207-%20Primera%20parte%3A%20Trucos%20nuevos%20de%20un%20perro%20viejo" title="Blogger Post" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/blogger.png" width="16" height="16" alt="Blogger Post"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fblog.aquait.info%2F2011%2F08%2Fjboss-as-7-primera-parte-trucos-nuevos-de-un-perro-viejo%2F&amp;linkname=JBoss%20AS%207-%20Primera%20parte%3A%20Trucos%20nuevos%20de%20un%20perro%20viejo" title="Digg" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.aquait.info%2F2011%2F08%2Fjboss-as-7-primera-parte-trucos-nuevos-de-un-perro-viejo%2F&amp;linkname=JBoss%20AS%207-%20Primera%20parte%3A%20Trucos%20nuevos%20de%20un%20perro%20viejo" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_google_reader" href="http://www.addtoany.com/add_to/google_reader?linkurl=http%3A%2F%2Fblog.aquait.info%2F2011%2F08%2Fjboss-as-7-primera-parte-trucos-nuevos-de-un-perro-viejo%2F&amp;linkname=JBoss%20AS%207-%20Primera%20parte%3A%20Trucos%20nuevos%20de%20un%20perro%20viejo" title="Google Reader" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reader.png" width="16" height="16" alt="Google Reader"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aquait.info%2F2011%2F08%2Fjboss-as-7-primera-parte-trucos-nuevos-de-un-perro-viejo%2F&amp;title=JBoss%20AS%207-%20Primera%20parte%3A%20Trucos%20nuevos%20de%20un%20perro%20viejo" id="wpa2a_2"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aquait.info/2011/08/jboss-as-7-primera-parte-trucos-nuevos-de-un-perro-viejo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Java AppServer-04: Ejemplo</title>
		<link>http://blog.aquait.info/2010/10/java-appserver-04-ejemplo/</link>
		<comments>http://blog.aquait.info/2010/10/java-appserver-04-ejemplo/#comments</comments>
		<pubDate>Thu, 21 Oct 2010 22:49:34 +0000</pubDate>
		<dc:creator>Enrique</dc:creator>
				<category><![CDATA[AppServer]]></category>
		<category><![CDATA[Lab]]></category>

		<guid isPermaLink="false">http://blog.aquait.info/?p=247</guid>
		<description><![CDATA[Mucho artículo, mucho artículo&#8230; pero ¿cómo se usa? Bien, en este vamos a ver un ejemplo de como usar el AppServer. Antes de continuar, es muy importante tener en la cabeza el post http://blog.aquait.info/2009/10/180/ pues presenta la configuración del servidor. ¿Qué, cómo, dónde? Primero, vamos a definir “qué” queremos hacer. Una vez más, voy a [...]]]></description>
			<content:encoded><![CDATA[<p>Mucho artículo, mucho artículo&#8230; pero ¿cómo se usa? Bien, en este vamos a ver un ejemplo de como usar el AppServer. Antes de continuar, es muy importante tener en la cabeza el post <a href="http://blog.aquait.info/2009/10/180/">http://blog.aquait.info/2009/10/180/</a> pues presenta la configuración del servidor.<span id="more-247"></span></p>
<p>¿Qué, cómo, dónde?<br />
Primero, vamos a definir “qué” queremos hacer. Una vez más, voy a utilizar el clásico ejemplo de obtener PI desde el servidor. Luego veremos el “cómo”.</p>
<p>El “qué” refiere a la interfaz del servicio y el “cómo” a la implementación. Entonces tenemos que crear:</p>
<pre class="brush: java">package  ejemplo.client.services

// El “qué”
public interface MathService extends com.aquait.rpc.client.service.Service {
    double getPi();
}</pre>
<pre class="brush: java">// El “cómo”
package ejemplo.server.services

public class MathServiceImpl extends com.aquait.rpc.server.service.Service implements ejemplo.client.services.MathService {
    public double getPi() {
        return Math.PI;
    }
}</pre>
<p>¿Y ahora? Ahora hay que decir el “dónde”. Para esto configuramos el servidor. En el archivo services.config agregamos:</p>
<pre class="brush: java">service[math_service].interface = ejemplo.client.services.MathService
service[math_service].implementation =  ejemplo.server.services.MathServiceImpl</pre>
<p>Recordar “math_service” que será utilizado más adelante.<br />
El siguiente paso sería crear un jar con las clases e interfaces y copiar ese jar en el subdirectorio application.<br />
Con el comando start levantamos el servidor y deberíamos ver en el log, en el reporte de servicios, al querido MathService.</p>
<p>Mozo! Un PI por favor!<br />
Si todo está bien (y esperemos que así sea) estamos en condiciones de hacerle pedidos al servidor. Para esto, desde el cliente tenemos que conectarnos e invocar al servicio:</p>
<pre class="brush: java">// 1 – Nos conectamos al servidor
AppServerClient appServerClient = new AppServerClient("localhost", 6666);

// 2 - Obtenemos un proxy del servicio desado: “math_service”
MathService mathService = (MathService)appServerClient.getService("math_service");

// 3 - Invocamos al método deseado como si lo tuvieramos local
double pi = mathService.getPi();
System.out.println(pi);</pre>
<p>Todo esto y mucho más<br />
Esta es la versión simple. Pero en realidad, el servidor soporta seguridad, parámetros de inicialización de los servicios, pool de conexión a la base de datos, mensajería, módulos, etc. Esto se puede ver en el código fuente publicado en el artículo AppServer-03 en un módulo que se llama test.</p>
<p>Good luck!</p>
<p><a class="a2a_button_blogger_post" href="http://www.addtoany.com/add_to/blogger_post?linkurl=http%3A%2F%2Fblog.aquait.info%2F2010%2F10%2Fjava-appserver-04-ejemplo%2F&amp;linkname=Java%20AppServer-04%3A%20Ejemplo" title="Blogger Post" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/blogger.png" width="16" height="16" alt="Blogger Post"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fblog.aquait.info%2F2010%2F10%2Fjava-appserver-04-ejemplo%2F&amp;linkname=Java%20AppServer-04%3A%20Ejemplo" title="Digg" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.aquait.info%2F2010%2F10%2Fjava-appserver-04-ejemplo%2F&amp;linkname=Java%20AppServer-04%3A%20Ejemplo" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_google_reader" href="http://www.addtoany.com/add_to/google_reader?linkurl=http%3A%2F%2Fblog.aquait.info%2F2010%2F10%2Fjava-appserver-04-ejemplo%2F&amp;linkname=Java%20AppServer-04%3A%20Ejemplo" title="Google Reader" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reader.png" width="16" height="16" alt="Google Reader"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aquait.info%2F2010%2F10%2Fjava-appserver-04-ejemplo%2F&amp;title=Java%20AppServer-04%3A%20Ejemplo" id="wpa2a_4"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aquait.info/2010/10/java-appserver-04-ejemplo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java AppServer-03: Configuración y código</title>
		<link>http://blog.aquait.info/2009/10/180/</link>
		<comments>http://blog.aquait.info/2009/10/180/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 01:08:40 +0000</pubDate>
		<dc:creator>Enrique</dc:creator>
				<category><![CDATA[AppServer]]></category>
		<category><![CDATA[RPC]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Lab]]></category>

		<guid isPermaLink="false">http://blog.aquait.info/?p=180</guid>
		<description><![CDATA[Este es el último artículo de esta serie. En este voy a presentar como se configura el servidor y además voy a subir el código fuente. Estructura de directorios: aquait-appserver/ application/ db_connection_pool.config Configuración del módulo pool de conexiones a la base modules.config Configuración de los módulos services.config Configuración de los servicios messaging.config Configuración del módulo [...]]]></description>
			<content:encoded><![CDATA[<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } 		A:link { so-language: zxx } --></p>
<p style="margin-bottom: 0in; font-weight: normal;">Este es el último artículo de esta serie. En este voy a presentar como se configura el servidor y además voy a subir el código fuente.</p>
<p style="margin-bottom: 0in; font-weight: normal;"><span id="more-180"></span></p>
<p style="margin-bottom: 0in; font-weight: normal;">Estructura de directorios:</p>
<p style="margin-bottom: 0in;"><strong>aquait-appserver/</strong></p>
<ul>
<li><strong> application/</strong>
<ul>
<li>db_connection_pool.config	Configuración del módulo pool de conexiones a la base</li>
<li>modules.config		Configuración de los módulos</li>
<li>services.config 		Configuración de los servicios</li>
<li>messaging.config		Configuración del módulo de mensajería</li>
<li>security.config 		Configuración de seguridad</li>
</ul>
</li>
<li><strong> lib/</strong>
<ul>
<li>aquaitrt-bin_2009r1.jar	Runtime</li>
<li>mail.jar 			Servicio de mail</li>
</ul>
</li>
<li><strong> log/</strong></li>
<li>logging.config				Configuración de logging</li>
<li>server.config				Configuración del servidor</li>
<li>start.sh</li>
<li>stop.sh</li>
<li>start.cmd				       Scripts para iniciar y detener al servidor</li>
<li>start.sh</li>
<li>stop.cmd</li>
<li>stop.sh</li>
</ul>
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in;"><strong>logging.config</strong></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">handlers = java.util.logging.ConsoleHandler, java.util.logging.FileHandler </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"> </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">java.util.logging.FileHandler.level = ALL </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">java.util.logging.FileHandler.pattern = ./log/server.%u.txt </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">java.util.logging.FileHandler.limit = 50000 </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">java.util.logging.FileHandler.count = 1 </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">java.util.logging.FileHandler.formatter = com.aquait.utils.logging.ServerFormatter </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"> </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">java.util.logging.ConsoleHandler.level = INFO </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">java.util.logging.ConsoleHandler.formatter = com.aquait.utils.logging.ServerFormatter </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in; font-weight: normal;">Archivo que configura el logging. El servidor usa la API estándar de Java SE para logear. El archivo por defecto define dos handlers. El primero que genera archivos y el segundo logea a la consola. Por más detalles, ver http://java.sun.com/javase/6/docs/api/java/util/logging/package-summary.html.</p>
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;"><strong>server.config</strong></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># Server config </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"> </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># Server listening port </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">port = 6666 </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"> </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># Worker pool size </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">workers.poolsize = 10 </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"> </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># Shutdown password </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">shutdown.password = _shut_down_now_server_ </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in; font-weight: normal;">Este archivo define tres parámetros del servidor. Primero el puerto TCP/IP en el cual el servidor escucha conexiones. Los clientes se deberán conectar a este puerto. El segundo parámetro define la cantidad de workers (hilos) que atienden los pedidos de los clientes. Y el tercero es la contraseña para bajar el servidor. Se baja mediante el script stop que se comunica al puerto definido y manda un mensaje especial. El servidor solamente se puede bajar desde el mismo host en donde está ejecutando.</p>
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;"><strong>db_connection_pool.config</strong></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># DBConnectionPoolModule configuration </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># Examples: </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">#     url = jdbc:oracle:thin:@&lt;host&gt;:&lt;port&gt;:&lt;database&gt; </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">#     driverclass = oracle.jdbc.driver.OracleDriver </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">enable = false </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">url = &lt;url&gt; </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">username = &lt;user&gt; </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">password = &lt;pass&gt; </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">driverclass = &lt;driver_class&gt; </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">autocommit = false </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">poolsize = 5 </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">maxpoolsize = 10 </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in; font-weight: normal;">Este archivo controla los parámetros del pool de conexiones a la base de datos.</p>
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;"><strong>modules.config</strong></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># Modules to load </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># Format: </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">#       module.name = &lt;module_name&gt; </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">#       module[&lt;module_name&gt;].class = &lt;module_class&gt; </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">#</span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in; font-weight: normal;">En este archivo se delcaran los módulos que van a desplegarse en el servidor. Cada módulo puede tener una cantidad varible de parámetros.</p>
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;"><strong>messaging.config</strong></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># MessagingModule configuration </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">enable = false </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">poolsize = 10 </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"> # Security realms </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># Format (&lt;n&gt; starts at 0): </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">#       security_realm[&lt;n&gt;] = &lt;security_realm_class&gt; </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">#</span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in; font-weight: normal;">Este archivo configura la seguridad del servidor. Se pueden definir varios realms que se ejecutan en orden  para cada pedido de los clientes.</p>
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;"><strong>services.config</strong></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># Services </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># Format: </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">#       service[&lt;service_name&gt;].interface = &lt;service_interface&gt; </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">#       service[&lt;service_name&gt;].implementation = &lt;service_implementation&gt; </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">#       service[&lt;service_name&gt;].parameter[&lt;param_name&gt;] = &lt;param_value&gt; </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;"># </span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in; font-weight: normal;">Este archivo configura los servicios que se publican en el servidor. Para cada servicio hay que configurar la interfaz y la implementación de esta. Además, opcionalmente, se pueden agregar parámetros de inicialización.</p>
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in; font-weight: normal;">Con esto finalizamos esta serie. Siempre estoy a las orden ante cualquier consulta que tengan al respecto de este servidor.</p>
<p style="margin-bottom: 0in; font-weight: normal;">Bajar código fuente: <a href="http://blog.aquait.info/wp-content/uploads/2009/10/aquaitrt_2009-10-14.tar.gz">aquaitrt_2009-10-14.tar.gz</a></p>
<p style="margin-bottom: 0in; font-weight: normal;">
<p><a class="a2a_button_blogger_post" href="http://www.addtoany.com/add_to/blogger_post?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F10%2F180%2F&amp;linkname=Java%20AppServer-03%3A%20Configuraci%C3%B3n%20y%20c%C3%B3digo" title="Blogger Post" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/blogger.png" width="16" height="16" alt="Blogger Post"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F10%2F180%2F&amp;linkname=Java%20AppServer-03%3A%20Configuraci%C3%B3n%20y%20c%C3%B3digo" title="Digg" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F10%2F180%2F&amp;linkname=Java%20AppServer-03%3A%20Configuraci%C3%B3n%20y%20c%C3%B3digo" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_google_reader" href="http://www.addtoany.com/add_to/google_reader?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F10%2F180%2F&amp;linkname=Java%20AppServer-03%3A%20Configuraci%C3%B3n%20y%20c%C3%B3digo" title="Google Reader" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reader.png" width="16" height="16" alt="Google Reader"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aquait.info%2F2009%2F10%2F180%2F&amp;title=Java%20AppServer-03%3A%20Configuraci%C3%B3n%20y%20c%C3%B3digo" id="wpa2a_6"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aquait.info/2009/10/180/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Java AppServer-02: DBPool + Messaging</title>
		<link>http://blog.aquait.info/2009/10/java-appserver-02-dbpool-messaging/</link>
		<comments>http://blog.aquait.info/2009/10/java-appserver-02-dbpool-messaging/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 18:17:16 +0000</pubDate>
		<dc:creator>Enrique</dc:creator>
				<category><![CDATA[AppServer]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Lab]]></category>

		<guid isPermaLink="false">http://blog.aquait.info/?p=175</guid>
		<description><![CDATA[Siguiendo la exploración de los principales componentes de servidor, en este artículo vamos a ver el el componente de conexiones a la base de datos y el de mensajería. Los dos componentes se diseñaron e implementaron separadamente del servidor de aplicaciones, por lo que no están acoplados de ninguna forma. Para “agregarlos” al servidor, se [...]]]></description>
			<content:encoded><![CDATA[<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p style="margin-bottom: 0in;">Siguiendo la exploración de los principales componentes de servidor, en este artículo vamos a ver el el componente de conexiones a la base de datos y el de mensajería. Los dos componentes se diseñaron e implementaron separadamente del servidor de aplicaciones, por lo que no están acoplados de ninguna forma. Para “agregarlos” al servidor, se implementaron módulos del servidor que los adaptan. <span id="more-175"></span></p>
<p style="margin-bottom: 0in;">Pool de conexiones a la base de datos</p>
<p style="margin-bottom: 0in;">El pool implementado es muy sencillo. Tiene una colección de conexiones con un tamaño inicial (configurable) y en caso de que el cliente (en este caso el servidor de aplicaciones) necesite más, crea hasta un máximo (también configurable).</p>
<p style="margin-bottom: 0in; text-align: center;">
<div id="attachment_176" class="wp-caption aligncenter" style="width: 570px"><a href="http://blog.aquait.info/wp-content/uploads/2009/10/Java-AppServer-02-fig1.png"><img class="size-full wp-image-176 " title="Java-AppServer-02-fig1" src="http://blog.aquait.info/wp-content/uploads/2009/10/Java-AppServer-02-fig1.png" alt="Diseño del pool de conexiónes a la BD" width="560" height="426" /></a><p class="wp-caption-text">Diseño del pool de conexiónes a la BD</p></div>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p style="margin-bottom: 0in;">Los métodos startup() y shutdown() del módulo manejan el ciclo de vida del pool. El primero carga de un archivo de configuración -que veremos más adelante- los datos para crear el pool y el segundo mata a las conexiones activas.</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Mensajería</p>
<p style="margin-bottom: 0in; font-weight: normal;">El servicio de mensajería también es sencillo, pero potente. Poseé un pool de hilos que procesan los mensajes en form asíncrona. La clase Messaging tiene un conjunto de MessageHandlers que son los responsables de procesar los mensajes. Cuando llega un mensaje, este se le pasa a todos los handlers y cada uno es responsable de si lo procesa o no.</p>
<p style="margin-bottom: 0in; text-align: center;">
<div id="attachment_177" class="wp-caption aligncenter" style="width: 634px"><a href="http://blog.aquait.info/wp-content/uploads/2009/10/Java-AppServer-02-fig2.png"><img class="size-full wp-image-177 " title="Java-AppServer-02-fig2" src="http://blog.aquait.info/wp-content/uploads/2009/10/Java-AppServer-02-fig2.png" alt="Diseño del servicio de mensajería" width="624" height="435" /></a><p class="wp-caption-text">Diseño del servicio de mensajería</p></div>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p style="margin-bottom: 0in; font-weight: normal;">En el próximo artículo voy presentar la configuración del servidor y también voy a subir el código fuente. Hasta el próximo!</p>
<p><a class="a2a_button_blogger_post" href="http://www.addtoany.com/add_to/blogger_post?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F10%2Fjava-appserver-02-dbpool-messaging%2F&amp;linkname=Java%20AppServer-02%3A%20DBPool%20%2B%20Messaging" title="Blogger Post" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/blogger.png" width="16" height="16" alt="Blogger Post"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F10%2Fjava-appserver-02-dbpool-messaging%2F&amp;linkname=Java%20AppServer-02%3A%20DBPool%20%2B%20Messaging" title="Digg" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F10%2Fjava-appserver-02-dbpool-messaging%2F&amp;linkname=Java%20AppServer-02%3A%20DBPool%20%2B%20Messaging" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_google_reader" href="http://www.addtoany.com/add_to/google_reader?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F10%2Fjava-appserver-02-dbpool-messaging%2F&amp;linkname=Java%20AppServer-02%3A%20DBPool%20%2B%20Messaging" title="Google Reader" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reader.png" width="16" height="16" alt="Google Reader"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aquait.info%2F2009%2F10%2Fjava-appserver-02-dbpool-messaging%2F&amp;title=Java%20AppServer-02%3A%20DBPool%20%2B%20Messaging" id="wpa2a_8"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aquait.info/2009/10/java-appserver-02-dbpool-messaging/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Como elegir un framework web</title>
		<link>http://blog.aquait.info/2009/09/como-elegir-un-framework-web/</link>
		<comments>http://blog.aquait.info/2009/09/como-elegir-un-framework-web/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 02:20:23 +0000</pubDate>
		<dc:creator>Alejandro</dc:creator>
				<category><![CDATA[Arquitectura]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://blog.aquait.info/?p=134</guid>
		<description><![CDATA[Hoy en día casi todo proyecto de desarrollo tiene alguna interfaz web como parte del producto. Esto no es ningún desafío si tenemos un equipo el cual ya ha trabajado con este tipo de  proyectos. ¿Pero que pasa si el equipo no tiene experiencia en el desarrollo de aplicaciones web?]]></description>
			<content:encoded><![CDATA[<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --><br />
<strong><em>¿Como puedo saber cual es el mejor framework web para mi proyecto?</em></strong><em> </em></p>
<p style="margin-bottom: 0in">Hoy en día casi todo proyecto de desarrollo tiene alguna interfaz web como parte del producto. Esto no es ningún desafío si tenemos un equipo el cual ya ha trabajado con este tipo de  proyectos. ¿Pero que pasa si el equipo no tiene experiencia en el desarrollo de aplicaciones web?</p>
<p style="margin-bottom: 0in"><span id="more-134"></span></p>
<p style="margin-bottom: 0in" align="left">Por ejemplo, viene del mundo enterprise, con años de experiencia en sistema de mediano y gran porte con clientes realizados con frameworks GUIs como ser Swing.</p>
<p style="margin-bottom: 0in" align="left">Al principio seguramente subestimemos el mundo web pensando que todo es es un juego de niños que cualquiera puede hacer y que contratando a un diseñador web nuestros problemas van a estar solucionados. Pero obviamente uno está equivocado y ni bien comienza a estudiar lo básico se encuentra con una cantidad de conceptos no menores como ser  manejo de sesión, AJAX, CSS, XSS, SQL-Inyection que uno debe entender antes de poder realizar cualquier sistema.</p>
<p style="margin-bottom: 0in" align="left">Una vez que terminamos de estudiar estos conceptos y que nos volvemos a sentir seguros para comenzar es recién ahí que nuestro problema comienza. En ese momento es cuando la gran pregunta surge ¿Qué framework web (FW) es el que debo utilizar para mis proyectos?</p>
<p style="margin-bottom: 0in" align="left">Hace un par de años atrás esto no hubiera sido un problema, la respuesta probablemente hubiera  sido si estamos trabajando en Java, utiliza <strong>struts</strong><span style="font-weight: normal">. Pero hoy eso cambió debido a que solo para Java en la página </span><a href="http://java-source.net/open-source/web-frameworks">http://java-source.net/open-source/web-frameworks</a> podemos encontrar más de 40 frameworks, dentro de los cuales el que yo utilizo no está. Y ni hablar si entramos considerar FW de diferentes lenguaje de programación como ser Ruby, Python, php y .net . ¿Entonces como podemos hacer para responder semejante pregunta hoy en día?</p>
<p style="margin-bottom: 0in" align="left">A continuación voy a definir lo que IMHO son los factores que yo he utilizado para responder está pregunta y que pueden ser de ayuda a otros que se enfrenten a una situación similar. Partiremos de la base  que tenemos un equipo de desarrollo con experiencia en un lenguaje determinado el cual debemos reconvertir al desarrollo de aplicaciones web. Algunos de los puntos que se plantearán no tienen sentido por ejemplo para un desarrollador independiente o si se está armando un equipo desde cero. Cuando se trabaja con un equipo ya formado hay factores a considerar que no dependen directamente de la tecnología y que pueden determinar que el mejor FW del mundo, no sea la mejor elección, lo cual hace que la solución del vecino no siempre sea la solución adecuada para uno. Por lo tanto debemos tener sumo cuidado con nuestros pares cuando con su mejor intención nos recomiendan “él FW” ya que probablemente ellos no conozcan el contexto donde usted lo debe utilizar. Por último hay que ser realistas y saber que probablemente al finalizar el proceso de selección haya más de un FW que pueda ser utilizado y que la definición terminará siendo un tema de preferencia con un grado de incertidumbre. La respuesta final solo la sabrá luego de estar avanzado en el primer proyecto, pudiendo equivocarse y debiendo reconsiderar su decisión. Por tal motivo es importante elegir como primer experiencia un proyecto  no crítico.</p>
<p style="margin-bottom: 0in" align="left">Los puntos que voy a nombrar a continuación no están en un orden especial.</p>
<p><strong><em>Puntos a tener en cuenta a la hora de elegir un FW</em></strong><br />
<strong>Conocimientos del equipo</strong></p>
<p style="margin-bottom: 0in">Es de suma importancia evaluar en que se siente cómodo el equipo trabajando. Es decir si tengo todos programadores Java muy probablemente lo mejor sea buscar una FW dentro de Java de esta forma el equipo podrá aprender rápidamente el FW ya que no tiene que perder tiempo estudiando los detalles de otro lenguaje. Por otro lado FW buenos hay en casi todos los lenguajes así que no debería ser un problema fijar este punto. La excepción a esta regla sería si estamos trabajando con un lenguaje desactualizado como ser Clipper o Cobol. Pero en este caso estaremos ante una problema mayor que es una reconversión tecnológica de los sistemas.</p>
<p><strong>¿Necesitamos algo que solucione solo la presentación o tenemos que trabajar en todas las capas?</strong></p>
<p style="margin-bottom: 0in" align="left">Es importante determinar que grado de libertad tenemos a la hora de elegir. Es decir, estamos ante un caso en el cual tenemos un sistema ya armado al cual solo debemos darle la presentación web o estamos ante un caso en el cual podemos elegir desde la forma de presentar los datos hasta la forma de persistirlos. Dependiendo de esto nos convendrá utilizar algo que soluciones todo nuestro requerimientos o simplemente centrarnos en lo que necesitamos que es solucionar la presentación web. En base a lo anterior podemos dividir los FW dividir en dos grupos y así descartar el que no sea de nuestro interés. Los grupos serían:</p>
<p><em>Frameworks full stack</em></p>
<p style="margin-bottom: 0in" align="left">Son los que presentan una solución completa que va desde la capa de presentación hasta la capa de persistencia de la información. Los más nuevos están basados en el patrón MVC. Algunos ejemplos de estos  son:</p>
<ul>
<li>Rails en ruby y que podríamos decir que es la estrella del momento</li>
<li> Grails en Groovy</li>
<li>CakePhp en php</li>
<li>Spring Roo y SEAM en Java</li>
<li>Django en Python</li>
</ul>
<p style="margin-bottom: 0in" align="left">Detallar cada uno no es nuestra intención, simplemente me limitaré a comentar que la mayoría está basado en los principios de CoC (convention over configuration), DRY (don&#8217;t repeate yourself) y que su composición básica consta de un procesador de templates para el diseño de las vista (que generarán las páginas dinámicas), un despachador de HttpRequests que siguiendo determinadas convención decide a que servicio despachar el pedido. Para el manejo de los datos cuentan con un framework ORM que ofrece creación de consultas dinámicas y una cantidad de facilidades que simplifican el trabajo.</p>
<p><em>Solo de presentación:</em></p>
<p style="margin-bottom: 0in" align="left">Estos son aquellos que están orientados solo a la capa de presentación.</p>
<p style="margin-bottom: 0in" align="left">Ejemplos de este tipo son:</p>
<ul>
<li>GWT- Google Web Tookit:el cual genera una aplicación 100% JavaScript pero que es	programada en Java</li>
<li>JSF: Java Server Faces, es el framework de componentes oficial de Java</li>
<li>ASP.NET: que es LA opción dentro de Microsoft</li>
</ul>
<p><strong>Soporte (comunidad, fabricante, libros, certificación, perspectiva a futuro)</strong></p>
<p style="margin-bottom: 0in" align="left">Un punto importante, sobre todo en los proyectos OS, es ver la comunidad que hay al rededor del framework a utilizar. Es importante investigar si hay una empresa invirtiendo recursos en el desarrollo del producto o está movido pura y exclusivamente por la comunidad. En el último casó es cuando “el tamaño si importa” y dependiendo del tamaño de la comunidad en que se sustenta depende el soporte que podemos tener. Para esto la mejor forma es en la página del framework buscar que tantos reporte de bugs hay, que tan rápido se solucionan, cuantos desarrolladores hay corrigiendo tickets. Siguiendo en esta misma linea hay que ver cada cuanto sale una nueva versión y si hay versiones destinadas a generar una versiones estables del framework o si solo salen versiones cuando hay nuevas funcionalidades. Visto que vamos a tener que aprender a utilizar el framework hay que estudiar la calidad de la documentación de este, ver que tantos libros publicados (por ejemplo en Amazon) hay sobre el tema y si se ofrece algún tipo de certificación y/o capacitación.</p>
<p><strong>Existencia de proyectos exitosos</strong></p>
<p style="margin-bottom: 0in" align="left">Como nuestra intención es utilizar el FW para un producto que en algún momento deberá salir en producción seguramente no queramos ser los conejillos de indias. Si el FW es  mínimamente serio entonces debe tener en su sitio web referencia a  sistemas que están implementado con este.  No es una mala idea de ser posible dar una mirada a estos y ver que tan bien funcionan. Sería excelente poder encontrar un blog de uno de estos proyectos en el cual se comente la experiencia durante el desarrollo del sistema.</p>
<p><strong>Integración con la plataforma existente</strong></p>
<p style="margin-bottom: 0in" align="left">Si el proyecto va a formar parte de un ecosistema más complejo entonces hay que tomar en cuenta las posibilidades de integración que tiene el FW y si estas son aceptables dentro de la arquitectura de nuestro producto. Por ejemplo si tenemos que interactuar con un sistema JEE es importante determinar que facilidades para invocar servicios EJB me da el FW. Claro está que siempre es posible desarrollar una capa que se encargue de la interacción, pero si el FW lo soporta nativamente no solo nos ahorramos trabajo sino que estamos reutilizando algo que está probado y utilizado por otros.</p>
<p><strong>Curva de aprendizaje</strong></p>
<p style="margin-bottom: 0in" align="left">Este punto hoy en día es engañoso debido a que los FW modernos tienen una curva de aprendizaje muy rápida inicialmente pero que para llegar a niveles de expertos hay que dedicarle mucho tiempo como a cualquier otro framework. Si ha esto le sumamos que la mayoría de los FW son OS con una documentación de mala calidad, que  probablemente no exista soporte local y que para capacitarnos tengamos que viajar muchos kilómetros (por lo menos si están el el Sur como yo). Lo cual hace que la capacidad de aprendizaje del equipo sea un factor importante. En algunos casos para poder llegar a solucionar un problema será necesario estudiar el código fuente del FW. Si llegáramos a tener la suerte de que el presupuesto nos permitiera poder capacitar parte del equipo y/o de contratar soporte entonces no hay que dudarlo. Los dolores de cabeza y el tiempo que se puede ganar  seguramente lo vale.</p>
<p><strong>Probar, probar y probar</strong></p>
<p style="margin-bottom: 0in" align="left">Inevitablemente para poder determinar el FW tendremos que destinar recursos y realizar algunas pruebas antes de poder llegar a una conclusión aceptable y fundamentada. No es necesario probar todos para estar tranquilo de que estamos utilizando el mejor. Cuando evaluemos recordar que estamos buscando el adecuado para el contexto donde hay que usarlo y no el mejor en general. Con un buen análisis previo probablemente no debamos probar más de dos o tres FW. Para que la prueba sea lo más comparativa posible debemos elegir un proyecto tipo y e implementarlo con con los FW que vayamos a evaluar..</p>
<p><strong><em>¿Como comparamos los FW?</em></strong><em> </em></p>
<p style="margin-bottom: 0in" align="left">Para la comparación de los FW he utilizado una herramienta que a mi me ha ayudado a la hora de evaluar  y puede ser de ayuda para ustedes también. La herramienta es una simple tabla en la que refleja la mayoría de los puntos vistos. En esta tabla calificaremos los FW dándoles un puntaje donde para cada punto tendríamos un máximo asignable y la suma de los máximos te todos los puntos suma 100. Al definir máximos diferentes por puntos estamos priorizando los puntos a evaluar de acuerdo a nuestro contexto. Por ejemplo si estamos en un caso en el cual tenemos una cantidad de sistemas existentes con los cuales debemos interactuar seguramente la capacidad de integración del FW sea uno de los puntos más importantes a evaluar mientras que si no tenemos que interactuar con otros sistemas, tenemos tiempos tiranos y un equipo ya formado con poca experiencia web  entonces la curva de aprendizaje es un punto determinante en nuestra elección.</p>
<p style="margin-bottom: 0in" align="left">Para dejar en claro este punto vamos a ver un ejemplo:</p>
<p><!-- 		@page { margin: 0.79in } 		TD P { margin-bottom: 0in } 		TH P { margin-bottom: 0in } 		P { margin-bottom: 0.08in } --></p>
<table border="1" cellspacing="0" cellpadding="0" width="100%" rules="true" bordercolor="#555555">
<tbody>
<tr valign="top">
<th width="24%"></th>
<th width="6%">
<p align="center"><em><strong>Max</strong></em></p>
</th>
<th width="17%">
<p align="center"><em><strong>FW 1</strong></em></p>
</th>
<th width="17%">
<p align="center"><em><strong>FW 2</strong></em></p>
</th>
<th width="17%">
<p align="center"><em><strong>FW 3</strong></em></p>
</th>
<th width="17%">
<p align="center"><em><strong>FW 4</strong></em></p>
</th>
</tr>
<tr valign="top">
<td width="24%">
<p align="left"><em><strong>Soporte</strong></em></p>
</td>
<td width="6%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">25</span></p>
</td>
<td width="17%" bgcolor="#ffffff">
<p align="left">15</p>
</td>
<td width="18%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">10</span></p>
</td>
<td width="17%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">20</span></p>
</td>
<td width="18%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">5</span></p>
</td>
</tr>
<tr valign="top">
<td width="24%">
<p align="left"><em><strong>Proyecto exitoso</strong></em></p>
</td>
<td width="6%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">10</span></p>
</td>
<td width="17%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">5</span></p>
</td>
<td width="18%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">10</span></p>
</td>
<td width="17%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">10</span></p>
</td>
<td width="18%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">0</span></p>
</td>
</tr>
<tr valign="top">
<td width="24%">
<p align="left"><em><strong>Integración</strong></em></p>
</td>
<td width="6%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">50</span></p>
</td>
<td width="17%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">25</span></p>
</td>
<td width="18%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">40</span></p>
</td>
<td width="17%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">35</span></p>
</td>
<td width="18%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">45</span></p>
</td>
</tr>
<tr valign="top">
<td width="24%">
<p align="left"><em><strong>Curva aprendizaje</strong></em></p>
</td>
<td width="6%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">15</span></p>
</td>
<td width="17%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">15</span></p>
</td>
<td width="18%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">10</span></p>
</td>
<td width="17%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">10</span></p>
</td>
<td width="18%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">5</span></p>
</td>
</tr>
<tr valign="top">
<td width="24%">
<p align="left"><em><strong>Total:</strong></em></p>
</td>
<td width="6%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">100</span></p>
</td>
<td width="17%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">60</span></p>
</td>
<td width="18%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;"><strong>70</strong></span></p>
</td>
<td width="17%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;"><strong>75</strong></span></p>
</td>
<td width="18%" bgcolor="#ffffff">
<p align="left"><span style="color: #000000;">55</span></p>
</td>
</tr>
</tbody>
</table>
<p style="margin-bottom: 0in" align="left">
<p style="margin-bottom: 0in" align="left">La lectura que se pude hacer de la tabla anterior es que debemos realizar pruebas con el FW2 y el FW4 para definir cual de estos dos es el que vamos a utilizar. Gracias al estudio que realizamos redijimos por lo menos a la mitad la cantidad de FW a estudiar y tenemos una tabla que justifica nuestra elección.</p>
<p style="margin-bottom: 0in" align="left">Obviamente cuanta más filas le agreguemos a la tabla tendremos más información para justificar la elección.</p>
<p style="margin-bottom: 0in" align="left">Por las dudas aclaro que los máximos asignados son de ejemplos y ustedes deberían definir los suyos de acuerdo a sus necesidades.</p>
<p><strong>En resumen&#8230;</strong></p>
<p style="margin-bottom: 0in" align="left">En resumen a la hora de seleccionar un FW debemos seguir tres pasos:</p>
<ol>
<li>
<p style="margin-bottom: 0in; font-weight: normal;">Primero debemos evaluar 	los conocimientos del equipo y determinar que tipo de FW se quiere si uno que sea full-stack o solo presentación.</p>
</li>
<li>
<p style="margin-bottom: 0in; font-weight: normal;">Una vez tengamos esto y sabiendo el lenguaje de preferencia podemos buscar el subconjunto de FW a evaluar. Para facilitar la evaluación confeccionamos una planilla como la vista en el punto anterior.</p>
</li>
<li>
<p style="margin-bottom: 0in; font-weight: normal;">Por ultimo con los FW mejor ranqueados realizamos las pruebas las cuales se realizan con un mismo proyecto implementado en cada uno de los FW.</p>
</li>
</ol>
<p style="margin-bottom: 0in" align="left">Luego de todo esto podremos saber cual es el FW a utilizar. Parece mucho trabajo, no? Si seguro que lo es, pero es la única forma de poder tomar una decisión minimizando el riesgo de equivocarnos&#8230; y cuando la decisiones tecnológicas de una empresa depende de nosotros es bueno tener herramientas para justificar nuestras decisiones y sobro todo para asegurarnos el éxito de nuestro trabajo.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.aquait.info/2009/09/como-elegir-un-framework-web/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java AppServer-01: Intro Application Server</title>
		<link>http://blog.aquait.info/2009/09/112/</link>
		<comments>http://blog.aquait.info/2009/09/112/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 00:00:53 +0000</pubDate>
		<dc:creator>Enrique</dc:creator>
				<category><![CDATA[AppServer]]></category>
		<category><![CDATA[Lab]]></category>

		<guid isPermaLink="false">http://blog.aquait.info/?p=112</guid>
		<description><![CDATA[Ahora que tenemos un servicio RPC podemos usarlo como base para implementar un servidor de aplicaciones, pero solamente un servicio RPC no alcanza. Por esto, vamos a implementar estos módulos/servicios: Seguridad: autorización, autenticación y auditoria Pool de conexiones a la base de datos Servicio de mensajería asíncrona Y, además de tener una API para agregar [...]]]></description>
			<content:encoded><![CDATA[<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p style="margin-bottom: 0in; font-weight: normal;">Ahora que tenemos un servicio RPC podemos usarlo como base para implementar un servidor de aplicaciones, pero solamente un servicio RPC no alcanza. Por esto, vamos a implementar estos módulos/servicios:</p>
<ul>
<li>
<p style="margin-bottom: 0in; font-weight: normal;">Seguridad: 	autorización, autenticación y auditoria</p>
</li>
<li>
<p style="margin-bottom: 0in; font-weight: normal;">Pool de 	conexiones a la base de datos</p>
</li>
<li>
<p style="margin-bottom: 0in; font-weight: normal;">Servicio de 	mensajería asíncrona</p>
</li>
</ul>
<p style="margin-bottom: 0in; font-weight: normal;"><span id="more-112"></span></p>
<p style="margin-bottom: 0in; font-weight: normal;">Y, además de tener una API para agregar servicios, el servidor va a proveer una API para agregar módulos del usuario. Ahora el diagrama de componentes del servidor:</p>
<p style="margin-bottom: 0in; font-weight: normal; text-align: center;">
<div id="attachment_113" class="wp-caption aligncenter" style="width: 464px"><a href="http://blog.aquait.info/wp-content/uploads/2009/09/Java-AppServer-01-fig1.png"><img class="size-full wp-image-113 " title="Java-AppServer-01-fig1" src="http://blog.aquait.info/wp-content/uploads/2009/09/Java-AppServer-01-fig1.png" alt="Diagrama de componentes" width="454" height="151" /></a><p class="wp-caption-text">Diagrama de componentes</p></div>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p style="margin-bottom: 0in; font-weight: normal;">Los componentes de la capa superior utilizan funcionalidades de los componentes de la capa inferior. Ahora vamos a explorar cada uno de los componentes.</p>
<p style="margin-bottom: 0in; font-weight: normal;">
<p style="margin-bottom: 0in; font-weight: normal;">Security realms manager</p>
<p style="margin-bottom: 0in; font-weight: normal;">Esto es obligatorio en cualquier AppServer. En el Security Realms Manager se instalan los security realms. ¿Qué es un security realm? Conceptualmente es un componentes que controla el acceso al los servicios. Desde el punto de vista técnico, es la implementación de la interfaz:</p>
<p style="margin-bottom: 0in; font-weight: normal;">
<pre class="brush: java">public interface SecurityRealm {
    /**
     * The login method.
     * @param credentials The credentials to validate
     * @throws LoginException If an exeption ocurrs during login
     */
    void login(Credentials credentials) throws LoginException;

    /**
     * The logout method.
     * @param credentials The credentials
     */
    void logout(Credentials credentials);

    /**
     * This method returns true if and only if the service's method can be
     * executed with the given credentials.
     *
     * @param credentials the credentials of the executing user
     * @param serviceName the service name
     * @param methodName the method name to execute
     * @param params the paramenters to pass to the method
     * @throws NotExecutedException signals that the execution is not allowed for the given credentials, serviceName, methodName and params
     */
    void executionAllowed(Credentials credentials, String serviceName, String methodName, Object... params) throws NotExecutedException;
}</pre>
<p style="margin-bottom: 0in; font-weight: normal;">Son solamente tres métodos: login, logout y isExecutionAllowed. Los dos primeros refieren al concepto de autenticación y el tercero refiere al concepto de autorización, pero también se puede asociar a auditoría ya que siempre se ejecuta antes de realizar la invocación al servicio.</p>
<p style="margin-bottom: 0in; font-weight: normal;">El security realms manager utiliza el interceptor que aparece en Java RPC-07: en el método onPreExecution() se llama al método executionAllowed() del security realm y continúa la ejecución si este no da la excepción NotExecutedException. Por seguridad, tampoco ejecuta si ocurre cualquier otra excepción (o error) en el executionAllowed() y así evita que un bug quiebre el sistema de seguridad.</p>
<p style="margin-bottom: 0in; font-weight: normal;">Entonces poniendo código arbitrario en método executionAllowed() se puede autorizar o no la ejecución de un método de un servicio con determinados parámetros.</p>
<p style="margin-bottom: 0in; font-weight: normal;">El security realms manager maneja una colección de security realms. Se ejecutan todos y solamente se da por autorizada la llamada si todos autorizaron. El servidor tiene implementado un security realm abstracto que se basa en nombre de usuario y contraseña y otro security realm para hacer auditoría (logging).</p>
<pre class="brush: java">public abstract class AbstractUserPasswordSecurityRealm extends SecurityRealmAdapter {

    public AbstractUserPasswordSecurityRealm() {
    }

    public void login(Credentials c) throws LoginException {
        UserPasswordCredentials cred = (UserPasswordCredentials)c;
        if (cred != null) {
            String user = cred.getUser();
            String pass = cred.getPassword();
            validate(user, pass);
        } else {
            throw new LoginException("null credentials");
        }
    }

    public void executionAllowed(Credentials credentials, String serviceName, String methodName, Object... params) throws NotExecutedException {
        if (credentials == null) {
            throw new NotExecutedException("not logged in");
        }
    }

    public abstract void validate(String user, String pass) throws LoginException;
}</pre>
<p style="margin-bottom: 0in; font-weight: normal;">Module manager</p>
<p style="margin-bottom: 0in; font-weight: normal;">Como vimos, el servidor es extensible. ¿Pero cómo? Mediante módulos. Un módulo no es más que un bean que tiene un nombre y dos métodos para el manejo del ciclo de vida: startup() y shutdown(). Luego, el servidor tiene un método para obtener el módulo por su nombre. Como es tan simple la interfaz, es fácil adaptar cualquier servicio para incorporarlo al servidor. Por ejemplo, el servicio de mensajería asíncrona se implementó por separado y se creó un módulo para adaptarlo a este servidor de aplicaciones. Idem con el pool de conexiones a la base de datos. La interfaz:</p>
<pre class="brush: java">public interface Module {
    void setName(String name);
    String getName();

    void startup() throws Exception;
    void shutdown();
}</pre>
<p style="margin-bottom: 0in; font-weight: normal;">Para obtener un módulo desde un servicio, se lo pedimos al ServerContext:</p>
<p style="margin-bottom: 0in; font-weight: normal;" align="CENTER"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">ServerContext.getModule(moduleName);</span></span></p>
<p style="margin-bottom: 0in; font-weight: normal;">La clase ServerContext nuclea un conjunto de métodos estáticos que dan acceso a diferentes partes del servidor de aplicaciones. Los que más se desatacan son getModule() y getServerConfig(). El primero ya lo vimos. El segundo devuelve un Mapa con propiedades que se cargan de un archivo de configuración. Ya veremos la configuración en una sección dedicada a esta.</p>
<p style="margin-bottom: 0in; font-weight: normal;">Services Loader</p>
<p style="margin-bottom: 0in; font-weight: normal;">Este es el componente encargado de leer de un archivo de configuración y crear los servicios en el RPC. Está implementado como módulo así se puede reemplazar fácilmente por otro y se acopla al servidor. Básicamente lee de un archivo de configuración la descripción de los servicios con sus parámetros y los agrega al servidor.</p>
<p style="margin-bottom: 0in; font-weight: normal;">En el siguiente artículo voy a describir el pool de conexiones a la base de datos y el servicio de mensajería. También voy a describir los archivos de configuración.</p>
<p style="margin-bottom: 0in; font-weight: normal;">Hasta el próximo.</p>
<p style="margin-bottom: 0in; font-weight: normal;">
<p><a class="a2a_button_blogger_post" href="http://www.addtoany.com/add_to/blogger_post?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2F112%2F&amp;linkname=Java%20AppServer-01%3A%20Intro%20Application%20Server" title="Blogger Post" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/blogger.png" width="16" height="16" alt="Blogger Post"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2F112%2F&amp;linkname=Java%20AppServer-01%3A%20Intro%20Application%20Server" title="Digg" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2F112%2F&amp;linkname=Java%20AppServer-01%3A%20Intro%20Application%20Server" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_google_reader" href="http://www.addtoany.com/add_to/google_reader?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2F112%2F&amp;linkname=Java%20AppServer-01%3A%20Intro%20Application%20Server" title="Google Reader" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reader.png" width="16" height="16" alt="Google Reader"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2F112%2F&amp;title=Java%20AppServer-01%3A%20Intro%20Application%20Server" id="wpa2a_10"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aquait.info/2009/09/112/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java RPC-07: Extras y rendimiento</title>
		<link>http://blog.aquait.info/2009/09/java-rpc-07-extras-y-rendimiento/</link>
		<comments>http://blog.aquait.info/2009/09/java-rpc-07-extras-y-rendimiento/#comments</comments>
		<pubDate>Mon, 07 Sep 2009 01:07:39 +0000</pubDate>
		<dc:creator>Enrique</dc:creator>
				<category><![CDATA[RPC]]></category>
		<category><![CDATA[AppServer]]></category>
		<category><![CDATA[Lab]]></category>

		<guid isPermaLink="false">http://blog.aquait.info/?p=104</guid>
		<description><![CDATA[En este es último artículo de la serie RPC voy explorar algunas extras que tiene el servidor que nos van a servir para implementar un servidor de aplicaciones, pero sin perder generalidad. También vamos ha realizar un test de rendimiento, viendo el througput (pedidos por segundo) que tiene el servidor. Extras Los servicios en el [...]]]></description>
			<content:encoded><![CDATA[<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p style="margin-bottom: 0in;">En este es último artículo de la serie RPC voy explorar algunas extras que tiene el servidor que nos van a servir para implementar un servidor de aplicaciones, pero sin perder generalidad. También vamos ha realizar un test de rendimiento, viendo el througput (pedidos por segundo) que tiene el servidor.</p>
<p style="margin-bottom: 0in;"><span id="more-104"></span></p>
<p style="margin-bottom: 0in;">Extras</p>
<p style="margin-bottom: 0in;">Los servicios en el lado del servidor toman parámetros de inicialización. Esto nos va a permitir pasar datos al servicio para configurarlos. Estos parámetros se acceden mediante el método getParameters() de la clase Service, que devuelve un Mapa con la configuración.</p>
<p style="margin-bottom: 0in;">Validación de servicios</p>
<p style="margin-bottom: 0in;">Antes de agregar un servicio al servidor, se realizan los siguientes chequeos:</p>
<ul>
<li>
<p style="margin-bottom: 0in;">Que la 	implementación del servicio tiene que tener un constructor sin 	parámetros</p>
</li>
<li>
<p style="margin-bottom: 0in;">Que la implementación del 	servicio debe implementar la interfaz del servicio</p>
</li>
<li>
<p style="margin-bottom: 0in;">Qué no haya sobrecarga de métodos 	en el servicio</p>
</li>
<li>
<p style="margin-bottom: 0in;">Que el tipo de retorno como los 	parámetros de los métodos sean serializables</p>
</li>
</ul>
<p style="margin-bottom: 0in;">Estos chequeos ayudan a evitar errores comunes.</p>
<p style="margin-bottom: 0in;">Autorización de ejecución</p>
<p style="margin-bottom: 0in;">Antes de efectivamente ejecutar un método de un servicio, se invoca a un interceptor: onPreExecution. Si se ejecuta correctamente, entonces se pasa a invocar al servicio, si no se sale por excepción NotExecutedException. Esto nos va a servir para implementar, por ejemplo, mecanismos de seguridad y auditoría (logging).</p>
<p style="margin-bottom: 0in;">Rendimiento</p>
<p style="margin-bottom: 0in;">Con el test de rendimiento vamos comprobar ver si el diseño que hicimos es escalable como queríamos. El test se realizó en un notebook que tiene un CPU Intel modelo T9500 (C2D 2.6GHz, 6MB de cache core Penryn) con 2GB de RAM sobre Ubuntu 9.04 32 bits y con Java6. Los resultados fueron:</p>
<dl>
<dl>
<dd>
<table border="1" cellspacing="0" cellpadding="4" width="100%" bordercolor="#000000">
<col width="37"></col>
<col width="37"></col>
<tbody>
<tr valign="top">
<td width="9%" bgcolor="#000000"><span style="color: #ffffff;">Caso</span></td>
<td width="15%" bgcolor="#000000"><span style="color: #ffffff;">Procesos cliente</span></td>
<td width="16%" bgcolor="#000000"><span style="color: #ffffff;">Hilos por cliente</span></td>
<td width="14%" bgcolor="#000000"><span style="color: #ffffff;">Pedidos por hilo</span></td>
<td width="17%" bgcolor="#000000"><span style="color: #ffffff;">Total pedidos</span></td>
<td width="15%" bgcolor="#000000"><span style="color: #ffffff;">Tiempo (segs)</span></td>
<td width="15%" bgcolor="#000000"><span style="color: #ffffff;">Pedidos/ segundo</span></td>
</tr>
<tr valign="top">
<td width="9%">
<p align="right">1</p>
</td>
<td width="15%">
<p align="right">5</p>
</td>
<td width="16%">
<p align="right">30</p>
</td>
<td width="14%">
<p align="right">2500</p>
</td>
<td width="17%">
<p align="right">375000</p>
</td>
<td width="15%">
<p align="right">207</p>
</td>
<td width="15%">
<p align="right">1811,59</p>
</td>
</tr>
<tr valign="top">
<td width="9%">
<p align="right">2</p>
</td>
<td width="15%">
<p align="right">10</p>
</td>
<td width="16%">
<p align="right">30</p>
</td>
<td width="14%">
<p align="right">2500</p>
</td>
<td width="17%">
<p align="right">750000</p>
</td>
<td width="15%">
<p align="right">229</p>
</td>
<td width="15%">
<p align="right">3275,11</p>
</td>
</tr>
</tbody>
</table>
</dd>
</dl>
</dl>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p style="margin-bottom: 0in;">Si bien no es un test de stress muy riguroso, nos da una buena aproximación de la performance y escalabilidad del servicio: aumentando al doble la cantidad de pedidos, solamente sube el tiempo en 10,6%. También, hay un valor que se puede ajustar en la creación del servidor que es el tamaño del pool de workers de la capa Pedido que despachan pedidos a la capa Servicio. Por defecto es de tamaño 10, pero si se está ante una configuración multi CPU se puede subir este valor para obtener mejor rendimiento. En el caso del test de rendimiento se utilizó un pool de 10 workers.</p>
<p style="margin-bottom: 0in;">Un servidor de aplicaciones basado en un versión más vieja de este mecanismo de RPC está implantado hace ya varios años en uno de los bancos más importantes de Uruguay.</p>
<p style="margin-bottom: 0in;">En el próximo artículo vamos a comenzar con la introducción al servidor de aplicaciones y cuales son los componentes principales.</p>
<p style="margin-bottom: 0in;">Stay tuned!</p>
<p style="margin-bottom: 0in;">
<p><a class="a2a_button_blogger_post" href="http://www.addtoany.com/add_to/blogger_post?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2Fjava-rpc-07-extras-y-rendimiento%2F&amp;linkname=Java%20RPC-07%3A%20Extras%20y%20rendimiento" title="Blogger Post" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/blogger.png" width="16" height="16" alt="Blogger Post"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2Fjava-rpc-07-extras-y-rendimiento%2F&amp;linkname=Java%20RPC-07%3A%20Extras%20y%20rendimiento" title="Digg" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2Fjava-rpc-07-extras-y-rendimiento%2F&amp;linkname=Java%20RPC-07%3A%20Extras%20y%20rendimiento" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_google_reader" href="http://www.addtoany.com/add_to/google_reader?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2Fjava-rpc-07-extras-y-rendimiento%2F&amp;linkname=Java%20RPC-07%3A%20Extras%20y%20rendimiento" title="Google Reader" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reader.png" width="16" height="16" alt="Google Reader"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2Fjava-rpc-07-extras-y-rendimiento%2F&amp;title=Java%20RPC-07%3A%20Extras%20y%20rendimiento" id="wpa2a_12"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aquait.info/2009/09/java-rpc-07-extras-y-rendimiento/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java RPC-06: Capa Servicio</title>
		<link>http://blog.aquait.info/2009/09/java-rpc-06-capa-servicio/</link>
		<comments>http://blog.aquait.info/2009/09/java-rpc-06-capa-servicio/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 17:37:06 +0000</pubDate>
		<dc:creator>Enrique</dc:creator>
				<category><![CDATA[RPC]]></category>
		<category><![CDATA[AppServer]]></category>
		<category><![CDATA[Lab]]></category>

		<guid isPermaLink="false">http://blog.aquait.info/?p=79</guid>
		<description><![CDATA[En el artículo anterior vimos como estaba estructurada la capa Servicio y cuales eran las ideas principales. Pero para que sea realmente útil, nos quedaba responder las siguientes dos preguntas: ¿Cómo vamos a hacer para crear una instancia que sea un proxy de la clase MathServiceImpl, que implemente la interfaz MathService en forma automática y [...]]]></description>
			<content:encoded><![CDATA[<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } 		A:link { so-language: zxx } --></p>
<p style="margin-bottom: 0in;">En el artículo anterior vimos como estaba estructurada la capa Servicio y cuales eran las ideas principales. Pero para que sea realmente útil, nos quedaba responder las siguientes dos preguntas:</p>
<ul>
<li>
<p style="margin-bottom: 0in;">¿Cómo vamos a hacer para crear 	una instancia que sea un proxy de la clase MathServiceImpl, que 	implemente la interfaz MathService en forma automática y en tiempo 	de ejecución?</p>
</li>
<li>
<p style="margin-bottom: 0in;">¿Cómo vamos a hacer un 	RequestListener genérico que “decodifique” el RequestPacket e 	invoque al método correcto de MathServiceImpl?</p>
</li>
</ul>
<p style="margin-bottom: 0in;"><span id="more-79"></span></p>
<p style="margin-bottom: 0in;">Primero la primera. Para poder ejecutar un método, necesitamos saber: qué método de qué servicio y con qué parámetros lo vamos a ejecutar y mandar esa información al servidor; para esto vamos a crear la clase ServicePacket, que contiene esta información (el nombre del servicio, el nombre del método y un array de Object con los parámetros que toma el método).</p>
<p style="margin-bottom: 0in;">Ahora necesitamos el proxy. Afortunadamente Java nos provee un mecanismo para crear proxies en tiempo de ejecución. Para ver la documentación sobre proxies dinámicos ver <a href="http://java.sun.com/javase/6/docs/technotes/guides/reflection/proxy.html">http://java.sun.com/javase/6/docs/technotes/guides/reflection/proxy.html</a>. Ahh! El poder de la reflexión <img src='http://blog.aquait.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="margin-bottom: 0in;">Entonces, lo que vamos a hacer es un InvocationHandler que arme el ServicePacket y con ayuda de la capa Pedido lo mande al servidor:</p>
<pre class="brush: java">public class ServiceInvocationHandler implements InvocationHandler {
    // implements InvocationHandler
    public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
        RequestPacket req = new RequestPacket(new ServicePacket(serviceName, m.getName(), args), getUniqueKey());
        ResponsePacket result = requestManager.send(req);
        return result.getData();
    }
}</pre>
<p style="margin-bottom: 0in;">Vamos a tener una instancia de ServiceInvocationHandler por cada servicio y a cada servicio lo vamos a identificar con un String: serviceName.</p>
<p style="margin-bottom: 0in;">Para crear un proxy utilizaremos la clase ServiceProxyFactory que tiene el método createProxy() implementado según la guía sobre proxies dinámicos que va a crear por nosotros el ServiceInvocationHandler configurado. Y así obtenemos los proxies:</p>
<pre class="brush: java">MathService mathService = serviceProxyFactory.createProxy(“MathService”);</pre>
<p style="margin-bottom: 0in;">Luego la invocación:</p>
<pre class="brush: java">double pi = mathService.getPI();</pre>
<p style="margin-bottom: 0in;">No hay que crear ninguna clase extra ni nada por el estilo. Lo único que hay que hacer es pedirle a la serviceProxyFactory un proxy del servicio con el nombre del servicio deseado. Este nombre es el identificador con el que se registró el servicio en el servidor, por lo que es buena práctica ponerlo como constante en la interfaz del servicio.</p>
<p style="margin-bottom: 0in;">Obviamente hay más detalles de implementación, como que pasa con las excepciones en el servidor, pero no vale la pena adentrarnos en este punto ya que se puede ver claramente en la implementación de ServiceInvocationHandler.</p>
<p style="margin-bottom: 0in;">Ahora la segunda pregunta: ¿Cómo vamos a hacer un RequestListener genérico que “decodifique” el RequestPacket en invoque al método correcto de MathService?</p>
<p style="margin-bottom: 0in;">Simple, utilizando otra vez el poder de la reflexión. Vamos a explotar la capacidad de invocar métodos teniendo solamente el nombre y el nombre de la clase. Ahora es cuando vamos a “decodificar” RequestPacket, o mejor dicho, su payload: el ServicePacket. Con este payload, sabemos qué tenemos que ejecutar y con qué parámetros.</p>
<p style="margin-bottom: 0in;">Entonces, vamos a tener un componente RequestPacketListener para escuchar los pedidos de los clientes y con los datos en el ServicePacket podemos ejecutar el método requerido.</p>
<p style="margin-bottom: 0in;">Ahora un poco de UML:</p>
<p style="margin-bottom: 0in; text-align: center;">
<div id="attachment_82" class="wp-caption aligncenter" style="width: 636px"><img class="size-full wp-image-82" title="Java-RPC-06-fig1" src="http://blog.aquait.info/wp-content/uploads/2009/09/Java-RPC-06-fig1.png" alt="Diseño de la capa Servicio" width="626" height="459" /><p class="wp-caption-text">Diseño de la capa Servicio</p></div>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p style="margin-bottom: 0in;">La clase ServiceManager implementa RequestPacketListener, por lo que acepta paquetes de la capa Pedido. Además contiene la colección de servicios registrados. Cuando llega un ServicePacket, con el nombre obtiene la instancia del servicio, con el nombre del método, obtiene el objeto método a ejecutar y con los parámetros (array de Object) lo ejecuta. La respuesta le envía al la capa Pedido en forma de ResponsePacket.</p>
<p style="margin-bottom: 0in;">Las clases RPCClient y RPCServer nos dan las funcionalidades para interactuar con el RPC de forma sencilla, encapsulando código “pegamento”.</p>
<p style="margin-bottom: 0in;">Entonces, un servicio se define:</p>
<p style="margin-bottom: 0in;">La declaración:</p>
<pre class="brush: java">public interface MathService extends client.service.Service {
    String SERVICE_NAME = “math_service”;
    double getPI();
}</pre>
<p style="margin-bottom: 0in;">La implementación:</p>
<pre class="brush: java">public class MathServiceImpl extends server.service.Service implements MathService {
    @Override
    public double getPI() {
        return 3.1416;
    }
}</pre>
<p style="margin-bottom: 0in;">Se registra en el main del servidor:</p>
<pre class="brush: java">RPCServer rpcServer = new RPCServer(12345); // port en donde escucha el servidor
rpcServer.getServiceManager().addService(
            MathService.SERVICE_NAME, // nombre
            MathtService.class,       // interfaz
            MathServiceImpl.class);   // implementación</pre>
<p style="margin-bottom: 0in;">Y se utiliza en el cliente:</p>
<pre class="brush: java">RPCClient rpcClient = new RPCClient(“localhost”, 12345); // host y port en donde está el servidor
MathServie mathService = (MathService)rpcClient.getService(MathService.SERVICE_NAME);
double pi = mathService.getPI();</pre>
<p style="margin-bottom: 0in;">Así queda el RPC implementado. En el siguiente artículo estaré posteando el código fuente y señalando algunas características extras que no fueron descritas para no agregar complejidad pues no están estrictamente relacionadas con el RPC.</p>
<p style="margin-bottom: 0in;">Next!</p>
<p><a class="a2a_button_blogger_post" href="http://www.addtoany.com/add_to/blogger_post?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2Fjava-rpc-06-capa-servicio%2F&amp;linkname=Java%20RPC-06%3A%20Capa%20Servicio" title="Blogger Post" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/blogger.png" width="16" height="16" alt="Blogger Post"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2Fjava-rpc-06-capa-servicio%2F&amp;linkname=Java%20RPC-06%3A%20Capa%20Servicio" title="Digg" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2Fjava-rpc-06-capa-servicio%2F&amp;linkname=Java%20RPC-06%3A%20Capa%20Servicio" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_google_reader" href="http://www.addtoany.com/add_to/google_reader?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2Fjava-rpc-06-capa-servicio%2F&amp;linkname=Java%20RPC-06%3A%20Capa%20Servicio" title="Google Reader" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reader.png" width="16" height="16" alt="Google Reader"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aquait.info%2F2009%2F09%2Fjava-rpc-06-capa-servicio%2F&amp;title=Java%20RPC-06%3A%20Capa%20Servicio" id="wpa2a_14"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aquait.info/2009/09/java-rpc-06-capa-servicio/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Java RPC-05: Capa Servicio</title>
		<link>http://blog.aquait.info/2009/08/java-rpc-05-capa-servicio/</link>
		<comments>http://blog.aquait.info/2009/08/java-rpc-05-capa-servicio/#comments</comments>
		<pubDate>Sun, 30 Aug 2009 16:16:12 +0000</pubDate>
		<dc:creator>Enrique</dc:creator>
				<category><![CDATA[RPC]]></category>
		<category><![CDATA[AppServer]]></category>
		<category><![CDATA[Lab]]></category>

		<guid isPermaLink="false">http://blog.aquait.info/?p=66</guid>
		<description><![CDATA[Ahora si, la capa final. Lo que tiene que hacer esta capa es dar una interfaz amigable con el desarrollador para agregar y consumir servicios. Vimos que la API que daba la capa Pedido no era mala, pero se puede mejorar; tanto que podemos hacer que se parezca mucho a una invocación local. Idealmente queremos [...]]]></description>
			<content:encoded><![CDATA[<p style="margin-bottom: 0in;">Ahora si, la capa final. Lo que tiene que hacer esta capa es dar una interfaz amigable con el desarrollador para agregar y consumir servicios. Vimos que la API que daba la capa Pedido no era mala, pero se puede mejorar; tanto que podemos hacer que se parezca mucho a una invocación local. Idealmente queremos que tenga la misma sintaxis y semántica que en una llamada local.</p>
<p style="margin-bottom: 0in;"><span id="more-66"></span></p>
<p style="margin-bottom: 0in;">Lo primero que tenemos que hacer es ver como, desde el cliente, nos “enganchamos” al código del servidor. Esto lo vamos a hacer mediante un proxy. Un proxy no es otra cosa que un representante del servicio en el cliente. Entonces, las invocaciones que se hagan sobre el proxy van a terminar en servidor:</p>
<p style="margin-bottom: 0in; text-align: center;">
<div id="attachment_67" class="wp-caption aligncenter" style="width: 447px"><img class="size-full wp-image-67" title="Java-RPC-05-fig1" src="http://blog.aquait.info/wp-content/uploads/2009/08/Java-RPC-05-fig1.png" alt="Esquema de una llamada RPC" width="437" height="181" /><p class="wp-caption-text">Esquema de una llamada RPC</p></div>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p style="margin-bottom: 0in;">La idea es que este proxy utilice la capa Pedido: construyendo el RequestPacket, mandándolo con send() y devolviendo el ResponsePacket con la respuesta. Y en el servidor hay que tener un RequestPacketListener que “decodifique” el paquete y lo mande a ejecutar al método correcto de la implementación correcta.</p>
<p style="margin-bottom: 0in;">Entonces vamos a partir el servicio en dos: interfaz e implementación. La interfaz del servicio la usa el cliente:</p>
<pre class="brush: java">public interface MathService {
    double getPI();
}</pre>
<p style="margin-bottom: 0in;">Y su implementación está en el servidor:</p>
<pre class="brush: java">public class MathServiceImpl implements MathService {
    @Override
    public double getPI() {
        return 3.1416;
    }
}</pre>
<p style="margin-bottom: 0in;">El hecho de que MathServiceImpl implemente MathService, es por prolijidad, pero no es obligatorio.</p>
<p style="margin-bottom: 0in;">Ahora necesitamos una implementación del lado del cliente que utilice la capa Pedido:</p>
<pre class="brush: java">public class MathServiceProxy implements MathService {
    @Override
    public double getPI() {
        RequestPacket req = new RequestPacket(id, “obtener_valor_de_pi”);
        ResponsePacket resp = requestManager.send(req);
        return ((Double)resp.getData()).doubleValue();
    }
}</pre>
<p style="margin-bottom: 0in;">Y en el servidor:</p>
<pre class="brush: java">public class RemoteExecution implements RequestPacketListener {
    public ResponsePacket requestPacketArrived(RequestPacket requestPacket) {
        if (requestPacket.getPayload().equals(“obtener_valor_de_pi”)) {
            return new ResponsePacket(requestPacket.getKey(), mathServiceImpl.getPI());
        }
        return null;
    }
}</pre>
<p style="margin-bottom: 0in;">Para realizar la invocación desde el cliente:</p>
<pre class="brush: java">MathService mathService = new MathServiceProxy();
double pi = mathService.getPI();</pre>
<p style="margin-bottom: 0in;">Así invocamos desde el cliente, utilizando la interfaz, al servidor y obtenemos la respuesta. La capa Servicio nos va a dar todo esto (y más) automágicamente. Esto nos va a permitir que solamente tengamos que escribir la interfaz (MathService) y la implementación del servicio (MathServiceImpl).</p>
<p style="margin-bottom: 0in;">Las preguntas que quedan son:</p>
<ul>
<li>
<p style="margin-bottom: 0in;">En el cliente: ¿Cómo vamos a 	hacer para crear una instancia que sea un proxy de la clase 	MathServiceImpl, que implemente la interfaz MathService en forma 	automática y en tiempo de ejecución?</p>
</li>
<li>
<p style="margin-bottom: 0in;">En el servidor: ¿Cómo vamos a 	hacer un RequestListener genérico que “decodifique” el 	RequestPacket en invoque al método correcto de MathService?</p>
</li>
</ul>
<p style="margin-bottom: 0in;">Estas dos preguntas las vamos a responder en el próximo artículo <img src='http://blog.aquait.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><a class="a2a_button_blogger_post" href="http://www.addtoany.com/add_to/blogger_post?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F08%2Fjava-rpc-05-capa-servicio%2F&amp;linkname=Java%20RPC-05%3A%20Capa%20Servicio" title="Blogger Post" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/blogger.png" width="16" height="16" alt="Blogger Post"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F08%2Fjava-rpc-05-capa-servicio%2F&amp;linkname=Java%20RPC-05%3A%20Capa%20Servicio" title="Digg" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F08%2Fjava-rpc-05-capa-servicio%2F&amp;linkname=Java%20RPC-05%3A%20Capa%20Servicio" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_google_reader" href="http://www.addtoany.com/add_to/google_reader?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F08%2Fjava-rpc-05-capa-servicio%2F&amp;linkname=Java%20RPC-05%3A%20Capa%20Servicio" title="Google Reader" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reader.png" width="16" height="16" alt="Google Reader"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aquait.info%2F2009%2F08%2Fjava-rpc-05-capa-servicio%2F&amp;title=Java%20RPC-05%3A%20Capa%20Servicio" id="wpa2a_16"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aquait.info/2009/08/java-rpc-05-capa-servicio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java RPC-04: Capa Pedido</title>
		<link>http://blog.aquait.info/2009/08/java-rpc-04-capa-pedido/</link>
		<comments>http://blog.aquait.info/2009/08/java-rpc-04-capa-pedido/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 19:57:51 +0000</pubDate>
		<dc:creator>Enrique</dc:creator>
				<category><![CDATA[RPC]]></category>
		<category><![CDATA[AppServer]]></category>
		<category><![CDATA[Lab]]></category>

		<guid isPermaLink="false">http://blog.aquait.info/?p=56</guid>
		<description><![CDATA[Hoy examinaremos una de las capas más complejas del sistema, la capa Request. Comparando esta capa con las anteriores (Conexión y Sesión) que son básicamente pasa-mano, esta capa agrega buena parte de la complejidad del sistema. ¿Por qué? Porque es la encargada del manejo de pedidos y respuestas concurrentes entre los clientes y el servidor. [...]]]></description>
			<content:encoded><![CDATA[<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p style="margin-bottom: 0in;">Hoy examinaremos una de las capas más complejas del sistema, la capa Request. Comparando esta capa con las anteriores (Conexión y Sesión) que son básicamente pasa-mano, esta capa agrega buena parte de la complejidad del sistema. ¿Por qué? Porque es la encargada del manejo de pedidos y respuestas concurrentes entre los clientes y el servidor.</p>
<p style="margin-bottom: 0in;"><span id="more-56"></span></p>
<p style="margin-bottom: 0in;">En las decisiones tomadas en el diseño de esta capa primó la escalabilidad: capacidad del servidor de procesar gran cantidad de pedidos y conservando tiempos de respuestas bajos. (Aclaro que no se busca desarrollar el RPC con más rendimiento del mundo, me conformo con uno que sea útil para cargas medias. Habrá un artículo dedicado al rendimiento del sistema).</p>
<p style="margin-bottom: 0in;">Al diseñador!</p>
<p style="margin-bottom: 0in;">Primero vamos a analizar el lado del servidor. Lo que buscamos es la capacidad de recibir y procesar pedidos concurrentemente, y claro, enviar las respuestas correspondientes. Siguiendo con la filosofía de las capas inferiores, vamos a tener la interfaz RequestPacketListener para escuchar pedidos, RequestPacket y se van a responder con la clase ResponsePacket.</p>
<p style="margin-bottom: 0in; text-align: center;">
<div id="attachment_57" class="wp-caption aligncenter" style="width: 610px"><img class="size-full wp-image-57" title="Java-RPC-04-fig1" src="http://blog.aquait.info/wp-content/uploads/2009/08/Java-RPC-04-fig1.png" alt="Diseño de la capa Sesión" width="600" height="466" /><p class="wp-caption-text">Diseño de la capa Pedido, lado servidor</p></div>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p style="margin-bottom: 0in;">La clase principal es RequestManager. Al implementar SessionPacketListener tiene la capacidad de recibir los mensajes de la capa Session y procesarlos. “Procesarlos” significa notificar al RequestPacketListener asociado. Ahora, para que esto sea concurrente, nos vamos a valer de la clase ThreadPoolExectutor para despachar los pedidos. Este Executor tiene un pool de threads -workers- que serán los que en definitiva invocan a requestPacketArrived() del RequestPacketListener para notificar la llegada del pedido. Antes de iniciar el procesamiento, a estos workers se les setea el contexto, que es el Map&lt;String, Object&gt; de Session; esto se hace mediante la clase WorkerContext.</p>
<p style="margin-bottom: 0in;">Ahora el cliente. En principio esta capa del lado del cliente podría ser simplemente otro pasamano, pero como queremos que un mismo cliente pueda realizar varios pedidos concurrentemente, tenemos que dale un poco más de pienso. Además, vamos a implementar un send() sincrónico. Así, podemos escribir:</p>
<pre class="brush: java">ResponsePacket response = requestManager.send(request);</pre>
<p style="margin-bottom: 0in;">Entonces ya esto se está pareciendo cada vez más a un RPC.</p>
<p style="margin-bottom: 0in;">Pero, cómo hacer para que una operación que es naturalmente asíncrona  (el send de sockets), sea sincrónica? Simple, utilizando semáforos (¡busy-waiting está prohibido!). Por cada pedido se va a crear un semáforo (Future) sobre el cual vamos a esperar la respuesta luego de enviar el pedido al servidor. Cuando la respuestas llega se notifica y el atributo data está cargado. Como queremos que un mismo cliente pueda realizar varios pedidos concurrentemente, vamos a tener una colección de estos semáforos.</p>
<p style="margin-bottom: 0in;">El atributo key en las clases RequestPacket y ResponsePacket es para encontrar al destinatario de la respuesta.</p>
<p style="margin-bottom: 0in; text-align: center;">
<div id="attachment_59" class="wp-caption aligncenter" style="width: 565px"><img class="size-full wp-image-59" title="Java-RPC-04-fig2" src="http://blog.aquait.info/wp-content/uploads/2009/08/Java-RPC-04-fig21.png" alt="Diseño de la capa Pedido, lado cliente" width="555" height="407" /><p class="wp-caption-text">Diseño de la capa Pedido, lado cliente</p></div>
<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } --></p>
<p style="margin-bottom: 0in;">Bueno, ahora si, esto ya es un RPC: mediante el RequestManager, podemos realizar pedidos al servidor y esperar la respuesta. Mientras el cliente espera, el servidor procesa la respuesta con el RequestPacketListener.</p>
<p style="margin-bottom: 0in;">Entonces, para implementar un método remoto, tenemos que crear un RequestPacketListener que haga lo que necesitamos y desde el cliente, mandar el RequestPacket con el método send de la clase RequestManager:</p>
<pre class="brush: java">RequestPacket req = new RequestPacket(key, “obtener_valor_de_pi”);
ResponsePacket resp = requestManager.send(req);
double pi = (Double)resp.getData();</pre>
<p style="margin-bottom: 0in;">Y en el servidor:</p>
<pre class="brush: java">public class RemoteExecution implements RequestPacketListener {
    public ResponsePacket requestPacketArrived(RequestPacket requestPacket) {
        if (requestPacket.getPayload().equals(“obtener_valor_de_pi”)) {
            return new ResponsePacket(requestPacket.getKey(), 3.1416);
        }
        return null;
    }
}</pre>
<p><span style="font-family: Liberation Mono,monospace;"> </span>Si bien este mecanismo es válido, está lejos de lo que queríamos; que era tener la misma sintaxis que la invocación a métodos locales:</p>
<pre class="brush: java">double pi = mathService.getPI();</pre>
<p style="margin-bottom: 0in;">Y su implementación:</p>
<pre class="brush: java">public MathService {
    public double getPI() {
        return 3.1416;
    }
}</pre>
<p style="margin-bottom: 0in;">Si podemos lograr esto último, estamos en la situación que queríamos desde el principio. En el próximo artículo vamos a ver la capa Servicio que, entre otras cosas, nos va a resolver este problema.</p>
<p style="margin-bottom: 0in;">Hasta el próximo!</p>
<p><a class="a2a_button_blogger_post" href="http://www.addtoany.com/add_to/blogger_post?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F08%2Fjava-rpc-04-capa-pedido%2F&amp;linkname=Java%20RPC-04%3A%20Capa%20Pedido" title="Blogger Post" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/blogger.png" width="16" height="16" alt="Blogger Post"/></a><a class="a2a_button_digg" href="http://www.addtoany.com/add_to/digg?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F08%2Fjava-rpc-04-capa-pedido%2F&amp;linkname=Java%20RPC-04%3A%20Capa%20Pedido" title="Digg" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/digg.png" width="16" height="16" alt="Digg"/></a><a class="a2a_button_reddit" href="http://www.addtoany.com/add_to/reddit?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F08%2Fjava-rpc-04-capa-pedido%2F&amp;linkname=Java%20RPC-04%3A%20Capa%20Pedido" title="Reddit" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reddit.png" width="16" height="16" alt="Reddit"/></a><a class="a2a_button_google_reader" href="http://www.addtoany.com/add_to/google_reader?linkurl=http%3A%2F%2Fblog.aquait.info%2F2009%2F08%2Fjava-rpc-04-capa-pedido%2F&amp;linkname=Java%20RPC-04%3A%20Capa%20Pedido" title="Google Reader" rel="nofollow" target="_blank"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/icons/reader.png" width="16" height="16" alt="Google Reader"/></a><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fblog.aquait.info%2F2009%2F08%2Fjava-rpc-04-capa-pedido%2F&amp;title=Java%20RPC-04%3A%20Capa%20Pedido" id="wpa2a_18"><img src="http://blog.aquait.info/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://blog.aquait.info/2009/08/java-rpc-04-capa-pedido/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

