<?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; Lab</title>
	<atom:link href="http://blog.aquait.info/tag/lab/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>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_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/2010/10/java-appserver-04-ejemplo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GWT Reflection</title>
		<link>http://blog.aquait.info/2009/12/gwt-reflection/</link>
		<comments>http://blog.aquait.info/2009/12/gwt-reflection/#comments</comments>
		<pubDate>Sun, 06 Dec 2009 00:32:02 +0000</pubDate>
		<dc:creator>Enrique</dc:creator>
				<category><![CDATA[GWT]]></category>
		<category><![CDATA[Lab]]></category>

		<guid isPermaLink="false">http://blog.aquait.info/?p=188</guid>
		<description><![CDATA[Intro Siguiendo en la linea de la introspección, hoy vamos a ver una simple reflexión que nos va a permitir invocar sobre una instancia de una clase a métodos por su nombre. What for? La reflexión es una característica interesante, que se hace fundamental a la hora de diseñar componentes genéricos. Nos permite crear instancias [...]]]></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;">Intro</p>
<p style="margin-bottom: 0in;">Siguiendo en la linea de la introspección, hoy vamos a ver una simple reflexión que nos va a permitir invocar sobre una instancia de una clase a métodos por su nombre.</p>
<p style="margin-bottom: 0in;"><span id="more-188"></span></p>
<p style="margin-bottom: 0in;">What for?</p>
<p style="margin-bottom: 0in;">La reflexión es una característica interesante, que se hace fundamental a la hora de diseñar componentes genéricos. Nos permite crear instancias de determinada clase con el nombre de la clase o también invocar métodos sobre una instancia de una clase teniendo el nombre del método. Esto, por ejemplo, nos simplifica enormemente la implementación del patrón command.</p>
<p style="margin-bottom: 0in;">How? What?!</p>
<p style="margin-bottom: 0in;">En GWT (al menos hasta la 1.7) no hay reflexión. Lo que vamos a hacer en esta implementación de reflexión, es proveer un mecanismo para invocar métodos por nombre. Suponiendo que tenemos una clase llamada <strong>MiClase</strong> que tiene un método llamado <strong>miMetodo</strong> buscamos poder hacer algo así:</p>
<p style="margin-bottom: 0in;">
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">MiClase instancia = new MiClase();</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">String nombreMetodo = “miMetodo”;</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">Object[] parametros = new Object[]{...};</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">invocar(instancia, nombreMetodo, parametros);</span></span></pre>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Enter generators!</p>
<p style="margin-bottom: 0in;">Lo que vamos a hacer es que GWT genere la clase MiClaseReflection. ¿Cómo? Usando generators. Esta es una característica bien interesante de GWT. El foco de este artículo no está en explicar generators, hay mucha literatura en Internet. Acá va un link: <a href="http://code.google.com/intl/es/webtoolkit/doc/1.6/DevGuideCodingBasics.html#DevGuideDeferredBinding">http://code.google.com/intl/es/webtoolkit/doc/1.6/DevGuideCodingBasics.html#DevGuideDeferredBinding</a>. Igual no hay que ser un experto para entender lo que vamos a hacer.</p>
<p style="margin-bottom: 0in;">Básicamente vamos a escribir una clase que genere el código de MiClaseReflection, que tiene un único método -invocar- que es una cadena if..elseif..else que pregunta por cada método de MiClase y si alguna coincide, se lo invoca. Sería algo como esto:</p>
<p style="margin-bottom: 0in;">
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">if (nombreMetodo.equals(“miMetodo1”)) {</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    target.miMetodo1(params);  // void</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">} else if (nombreMetodo.equals(“miMetodo2”)) {</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    return target.miMetodo2(params); // no void</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">} else {</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    throw new Exception(“método no encontrador: ” + nombreMetodo);</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">}</span></span></pre>
<p style="margin-bottom: 0in;">Obviamente falta chequeos de parámetros.</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Para no tener que realizar ningún paso previo a la compilación generando la clase con alguna utilidad externa vamos a usar la API que tiene GWT que permite extender el compilador (com.google.gwt.core.ext). NOTA: Los que hayan utilizado APT de Java van ver unas cuantas similitudes (<a href="http://java.sun.com/javase/6/docs/technotes/guides/apt/index.html">http://java.sun.com/javase/6/docs/technotes/guides/apt/index.html</a>).</p>
<p style="margin-bottom: 0in;">Cuando el compilador de GWT encuentra con la instrucción GWT.create(class) –que devuelve una implementación de la interfaz class– invoca al generador asociado a la interfaz class (esta asociación se declara en el gwt.xml del módulo). En este generador se “escribe” el código que implementa la interfaz class. Para escribir este código tenemos la asistencia de la API com.google.gwt.core.ext.typeinfo que recuerda mucho a la API Mirror Reflection de Java.</p>
<p style="margin-bottom: 0in;">Generate</p>
<p style="margin-bottom: 0in;">La instrucción GWT.create() toma una interfaz y devuelve una implementación de la misma. Entonces vamos definir una interfaz de marca y la vamos a llamar Reflectable. Toda clase que queramos tener soporte de reflexión va a tener que implementar esta interfaz:</p>
<p style="margin-bottom: 0in;">
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">public interface Reflectable {</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">}</span></span></pre>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Entonces la clase MiClase:</p>
<p style="margin-bottom: 0in;">
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">public class MiClase implements Reflectable {</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    void miMetodo1();</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    int miMetodo2();</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">}</span></span></pre>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Además, tenemos que tener la interfaz de idioma de la reflexión:</p>
<p style="margin-bottom: 0in;">
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">public interface Reflection&lt;I extends Reflectable&gt; {</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    Object invoke(I target, String methodName, Object... params)</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    throws InvocationException;</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">}</span></span></pre>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Para obtener una reflexión y usarla suponiendo que <strong>miMetodo</strong> no tiene parámetros:</p>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">MiClase objeto = new MiClase();</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">Reflection&lt;MiClase&gt; reflection = GWT.create(MiClase.class);</span></span></pre>
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">reflection.invoke(objeto, “miMetodo”);</span></span></pre>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Para asociar el generador con la interfaz Reflectable, agregamos el siguiente fragmento al :</p>
<p style="margin-bottom: 0in;">
<pre style="margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    &lt;generate-with class="com.aquait.utils.gwt.rebind.ReflectionGenerator"&gt;</span></span></pre>
<pre style="margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">        &lt;when-type-assignable class="com.aquait.utils.gwt.reflection.Reflectable"/&gt;</span></span></pre>
<pre style="margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">    &lt;/generate-with&gt;</span></span></pre>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Así, cuando el compilador de GWT encuentra GWT.create(MiClase.class), llama al generador pues la clase MiClase implementa Reflectable. Luego, tenemos una implementación de la interfaz Reflectable para la clase MiClase.</p>
<p style="margin-bottom: 0in;">Para usarlo en un proyecto, hay que agregar esto en el &lt;modulo&gt;.gwt.xml:</p>
<p style="margin-bottom: 0in;">
<pre style="margin-left: 0.49in; margin-bottom: 0in;"><span style="font-family: Liberation Mono,monospace;"><span style="font-size: x-small;">&lt;inherits name="com.aquait.utils.gwt.Reflection"/&gt;</span></span></pre>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">El JAR se puede descargar de acá: <a href="http://blog.aquait.info/wp-content/uploads/2009/12/introspection-reflection4gwt.jar_.gz">introspection-reflection4gwt.jar</a></p>
<p style="margin-bottom: 0in;">Nota: Este JAR tiene una versión actualizada de la introspección que elimina los métodos getIntrospectable() y setIntrospectable() de la interfaz Introspection. Por lo tanto, los métodos getProperty() y setProperty() toman como primer parámetro al Introspectable.</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%2F12%2Fgwt-reflection%2F&amp;linkname=GWT%20Reflection" 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%2F12%2Fgwt-reflection%2F&amp;linkname=GWT%20Reflection" 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%2F12%2Fgwt-reflection%2F&amp;linkname=GWT%20Reflection" 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%2F12%2Fgwt-reflection%2F&amp;linkname=GWT%20Reflection" 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%2F12%2Fgwt-reflection%2F&amp;title=GWT%20Reflection" 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/2009/12/gwt-reflection/feed/</wfw:commentRss>
		<slash:comments>3</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>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>GWT Introspection</title>
		<link>http://blog.aquait.info/2009/09/introspeccion-en-gwt/</link>
		<comments>http://blog.aquait.info/2009/09/introspeccion-en-gwt/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 18:23:27 +0000</pubDate>
		<dc:creator>Enrique</dc:creator>
				<category><![CDATA[GWT]]></category>
		<category><![CDATA[Lab]]></category>

		<guid isPermaLink="false">http://blog.aquait.info/?p=89</guid>
		<description><![CDATA[Intro Una de las características que más se extrañan a la hora de utilizar GWT es la capacidad de Java de realizar introspección sobre beans. La causa de esta limitación es que GWT no tiene emulación la API reflexión (java.lang.reflect). En este artículo vamos a ver como podemos implementar una suerte de introspección en GWT. [...]]]></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;">Intro</p>
<p style="margin-bottom: 0in;">Una de las características que más se extrañan a la hora de utilizar GWT es la capacidad de Java de realizar introspección sobre beans. La causa de esta limitación es que GWT no tiene emulación la API reflexión (java.lang.reflect). En este artículo vamos a ver como podemos implementar una suerte de introspección en GWT. También vamos a explorar algunas aplicaciones de introspección, ya que en principio no es trivial su utilidad.</p>
<p style="margin-bottom: 0in;"><span id="more-89"></span></p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">What for?</p>
<p style="margin-bottom: 0in;">Lo primero que vamos a ver es para qué queremos esto.</p>
<p style="margin-bottom: 0in;">Supongamos que queremos desarrollar un framework de componentes visuales que tenga data binding (capacidad de “enganchar” la propiedad de un objeto a un componente visual). Seguramente a todo aquel que le tocó la “maravillosa” tarea de implementar un CURD (ABM en criollo) se topó con la tediosa tarea de setear y leer de los componentes visuales al objeto y viceversa. Si te tocó hacer esto, algo malo hiciste <img src='http://blog.aquait.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Bueno, esta es una tarea tan aburrida como propensa a errores, sobre todo de Control-C + Control-V. Si pudieramos decir algo como: “este componente UI mira la propiedades tal de cual objeto”, entonces podemos aliviar bastante esta tarea ya que por ejemplo nos ahorramos todo el código de manejo de eventos.</p>
<p style="margin-bottom: 0in;">Entonces si podemos hacer esto, podemos construir un conjunto de componentes a los cuales simplemente le seteamos el bean y la propiedad que “mira” así cuando al componente se le cambia el valor, automáticamente se refleja en el bean y viceversa.</p>
<p style="margin-bottom: 0in;">Pero ¿cómo hacer esto sin introspeccion?</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">How? What?!</p>
<p style="margin-bottom: 0in;">Como vimos, en GWT (al menos hasta la 1.7) no hay reflexión, por lo que no nos queda más remedio que buscar otra forma de implementar introspección. Primero vamos a ver qué es la introspección en Java. Según el JavaDoc de la clase java.beans.Introspector:</p>
<p style="margin-left: 0.49in; margin-bottom: 0in;">“The Introspector class provides a standard way for tools to learn about the properties, events, and methods supported by a target Java Bean.”</p>
<p style="margin-bottom: 0in;">En español:</p>
<p style="margin-left: 0.49in; margin-bottom: 0in;">“La clase Introspector  provee una forma estándar para que herramientas descubran propiedades, eventos y métodos soportados por un Java Bean”.</p>
<p style="margin-bottom: 0in;">La parte que más nos interesa es la parte de las propiedades. O sea, queremos poder implementar un mecanismo con el cual se le pueda preguntar a un Java Bean cuales son sus propiedades y cuales son los valores de estas.</p>
<p style="margin-bottom: 0in;">La forma que vamos a implementar es creando una clase que sea la introspección para cada clase que queramos tener introspección.</p>
<p style="margin-bottom: 0in;">Entonces para la clase:</p>
<pre class="brush: java">public class Persona {
    private String nombre;
    private String direccion;
    private Date nacimiento;
    private boolean sexo;

    public Persona() {
    }

    public String getNombre() {
        return nombre;
    }
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    // ...más getters y setters...
}</pre>
<p style="margin-bottom: 0in;">Tenemos que implementar la clase de “introspección”:</p>
<pre class="brush: java">public PersonaIntrospection {
    private Persona persona;

    public PersonaIntrospeccion() {
    }

    public Persona getPersona() {
        return persona;
    }

    public Persona setPersona(Persona p) {
        persona = p;
    }

    public List&lt;String&gt; getProperties() {
        List&lt;String&gt; l = new ArrayList&lt;String&gt;();
        l.add(“nombre”);
        l.add(“direccion”);
        l.add(“nacimiento”);
        l.add(“sexo”);
    }

    public Object getProperty(String property) {
        if (“nombre”.equals(property))
            return persona.getNombre();
        else if (“direccion”.equals(property))
            return persona.getDireccion();
        else if (“nacimiento”.equals(property))
            return persona.getNacimiento();
        else if (“sexo”.equals(property))
            return persona.getSexo();
        else
            throw new IllegalArgumentException(property);
    }

    public void setProperty(String property, Object value) {
        if (“nombre”.equals(property))
            persona.setNombre((String)value);
        else if (“direccion”.equals(property))
            persona.setDireccion((String)value);
        else if (“nacimiento”.equals(property))
            persona.setNacimiento((Date)value);
        else if (“sexo”.equals(property))
            persona.setSexo((Boolean)value);
        else
            throw new IllegalArgumentException(property);
    }
}</pre>
<p style="margin-bottom: 0in;">Más allá de las optimizaciones que se le pueden hacer al código (como cachear la lista de propiedades), la idea es que se entienda de por qué esta clase nos da introspección sobre un objeto persona. Como ya se deben estar imaginando, la gracia es no tener que escribir la clase PersonaIntrospection. La gracia es trabajar menos en cosas aburridas y más en cosas “divertidas“ <img src='http://blog.aquait.info/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Enter generators!</p>
<p style="margin-bottom: 0in;">Lo que vamos a hacer es que GWT genere la clase PersonaIntrospection. ¿Cómo? Usando generators. Esta es una característica bien interesante de GWT. El foco de este artículo no está en explicar generators, hay mucha literatura en Internet. Acá va un link <a href="http://code.google.com/intl/es/webtoolkit/doc/1.6/DevGuideCodingBasics.html#DevGuideDeferredBinding">http://code.google.com/intl/es/webtoolkit/doc/1.6/DevGuideCodingBasics.html#DevGuideDeferredBinding</a>. Igual no hay que ser un experto para entender lo que vamos a hacer.</p>
<p style="margin-bottom: 0in;">Básicamente vamos a escribir una clase que genere el código de XxxIntrospection para la clase Xxx según vimos en el ejemplo de Persona. Y (para no tener que realizar ningún paso previo a la compilación generando la clase con alguna utilidad externa) vamos a usar la API que tiene GWT que permite extender el compilador (com.google.gwt.core.ext). NOTA: Los que hayan utilizado APT de Java van ver unas cuantas similitudes (<a href="http://java.sun.com/javase/6/docs/technotes/guides/apt/index.html">http://java.sun.com/javase/6/docs/technotes/guides/apt/index.html</a>).</p>
<p style="margin-bottom: 0in;">Cuando el compilador de GWT encuentra con la instrucción GWT.create(class) –que devuelve una implementación de la interfaz class– invoca al generador asociado a la interfaz class (esta asociación se declara en el gwt.xml del módulo). En este generador se “escribe” el código que implementa la interfaz class. Para escribir este código tenemos la asistencia de la API com.google.gwt.core.ext.typeinfo que recuerda mucho a la API Mirror Reflection de Java.</p>
<p style="margin-bottom: 0in;">
<p style="margin-bottom: 0in;">Generate</p>
<p style="margin-bottom: 0in;">Ahora vamos a ver el generador en si. Pero primero vamos a ver como se utiliza. GWT.create() toma una interfaz y devuelve una implementación de la misma. Entonces vamos definir una interfaz de marca y la vamos a llamar Introspectable. Toda clase que queramos tener soporte de introspección va a tener que implementar esta intefaz:</p>
<pre class="brush: java">public interface Introspectable {
}</pre>
<p style="margin-bottom: 0in;">Entonces la clase Persona:</p>
<pre class="brush: java">public class Persona implements Introspectable {
    // ... atributos y métodos ...
}</pre>
<p style="margin-bottom: 0in;">Además, tenemos que tener la interfaz de idioma de la introspección:</p>
<pre class="brush: java">public interface Introspection&lt;I extends Introspectable&gt; {
    I getIntrospectable();
    void setIntrospectable(I i);
    &lt;T&gt; T getProperty(String propName);
    void setProperty(String propName, Object value);
    Collection&lt;String&gt; getPropertyNames();
}</pre>
<p style="margin-bottom: 0in;">Y para obtener una introspección y usarla:</p>
<pre class="brush: java">Persona persona = new Persona();
Introspection&lt;Persona&gt; instrospection = GWT.create(Persona.class);
instrospection.setIntrospectable(persona);

for (String prop : instrospection.getPropertyNames()) {
    System.out.println(prop + " = " + instrospection.getProperty(prop));
}

String nombre = instrospection.getProperty("nombre");
String direccion = instrospection.getProperty("direccion");
Date nacimiento = instrospection.getProperty("nacimiento");
Boolean sexo = instrospection.getProperty("sexo");</pre>
<p style="margin-bottom: 0in;">Para asociar el generador con la interfaz Introspectable, agregamos el siguiente fragmento al :</p>
<pre class="brush: xml">&lt;generate-with class="com.aquait.utils.gwt.rebind.IntrospectionGenerator"&gt;
    &lt;when-type-assignable class="com.aquait.utils.gwt.introspection.Introspectable"/&gt;
&lt;/generate-with&gt;</pre>
<p style="margin-bottom: 0in;">Así, cuando el compilador de GWT encuentra GWT.create(Persona.class), llama al generador pues la clase Persona implementa Introspectable. Luego, tenemos una implementación de la interfaz Introspection para la clase Persona.</p>
<p style="margin-bottom: 0in;">Para usarlo en un proyecto, hay que agregar esto en el &lt;modulo&gt;.gwt.xml:</p>
<pre class="brush: xml">&lt;inherits name="com.aquait.utils.gwt.Introspection"/&gt;</pre>
<p style="margin-bottom: 0in;">El módulo GWT se puede descargar de acá: <a href="http://blog.aquait.info/wp-content/uploads/2009/09/introspection4gwt.jar">introspection4gwt</a></p>
<p style="margin-bottom: 0in;">EDIT: se actualizó el archivo debido a un pequeño bug.</p>
<p style="margin-bottom: 0in;">EDIT: se volvió a actualizar debido a un bug que hacía que no se tomaran en cuenta las propiedades de las super clases.</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%2Fintrospeccion-en-gwt%2F&amp;linkname=GWT%20Introspection" 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%2Fintrospeccion-en-gwt%2F&amp;linkname=GWT%20Introspection" 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%2Fintrospeccion-en-gwt%2F&amp;linkname=GWT%20Introspection" 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%2Fintrospeccion-en-gwt%2F&amp;linkname=GWT%20Introspection" 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%2Fintrospeccion-en-gwt%2F&amp;title=GWT%20Introspection" 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/introspeccion-en-gwt/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_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/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_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-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_20"><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>

