viernes, 15 de enero de 2010

Google Guice, breve reseña.

Google Guice es un framework para inyección de dependencias. Cuando nos encontramos frente al desarrollo de aplicaciones grandes (o al menos potencialmente grandes) en las que distintos equipos de desarrolladores codifican distintos módulos de una misma aplicación es el caso donde se presenta como obvia la necesidad de un bajo acoplamiento entre dichos módulos. Normalmente se presenta la necesidad de realizar tests automatizados de una o mas clases, o colaboraciones y dicho código posiblemente dependa de código de otro módulo que ni siquiera se encuentre desarrollado, o que resulte extremadamente costoso en tiempo o en recursos realizar dichos test. Aquí es cuando entra en juego la inyección de dependencias. No pretendo en este post explicar la inyección de dependencias en sí, para mayor información sobre ésta ver el siguiente enlace.

Goolge Guice es un excelente framework, el cual implementa el standard JSR 330 para la inyección de dependencias. Posee entre otras las siguientes características:
  • Inyección de dependencias en constructor.
  • Inyección de dependencias utilizando setters.
  • Inyección de dependencias directamente en los atributos de la clase.
  • Intercepción de métodos con filtro por anotaciones (especialmente útil para AOP).
  • Configuración programática de los módulos de la aplicación.
  • Definición de Fabricas (proveedores) y ámbitos para las instancias inyectadas.
  • Otras.
Gracias a estas características, estre framework resulta especialmente útil, algunos de los beneficios de utilizarlo son:
  • Generalización de aspectos en las aplicaciones y su consiguiente reducción de errores.
  • Escribimos código mas mantenible.
  • Escribimos código mejor testeable.
  • Escribimos código mucho más reutilizable.
En el siguiente ejemplo demostramos el uso de Google Guice para el módulo de recordatorio de cumpleaños en el appspot de este blog.

Primero demostraré un framgento de la clase encargada de la lógica de negocio de esta pequeña aplicación:
@Singleton
public class BirthDateManager {

private EntityManager em;

@Inject
public BirthDateManager(EntityManager em) {
this.em = em;
}
...
}


Podemos observar 3 cosas:
  1. Utilizamos el annotation @Singleton para indicarle al inyector que esta clase deberá instanciarla una única vez.
  2. Definimos el constructor que recibe las dependencias de esta clase de reglas de negocio de acuerdo con el patrón inyección de dependencias.
  3. Con la annotation @Inject le indicamos al inyector que debe inyectar dependencias.
Ahora observamos la clase que define el módulo donde configuraremos el inyector:

public class BirthDateModule extends AbstractModule {

@Override
protected void configure() {
bind(EntityManager.class).toProvider(PersistenceFacade.class);
}

}


Con esta simple línea le indicamos al inyector que debe obtener la dependencia de un proveedor, en este caso una fachada de persistencia. A continuación el código interesante de dicha fachada:

public class PersistenceFacade implements Provider<EntityManager> {

@Override
public EntityManager get() {
return emf.createEntityManager();
}
...
}

Vemos que nuestra clase proveedora deberá implementar la interfaz Provider para que Guice sepa cual es el método que nos provee la dependencia.

Finalmente vemos el código que pone todo junto. Obtenemos la clase de las reglas del negocio con las dependencias ya satisfechas a través de un inyector:

        Injector in = Guice.createInjector(new BirthDateModule());
BirthDateManager bdm = in.getInstance(BirthDateManager.class);



Como se puede ver resulta bastante simple:creamos un inyector a partir del módulo y luego le pedimos la clase de reglas del negocio a dicho inyector. Toda la magia ocurre en estas 2 líneas.

Con eso concluyo esta breve demostración de Google Guice. Espero que sea de utilidad.

Saludos!

miércoles, 13 de enero de 2010

Little Wings SRV

Acá les dejo un video de Stevie Ray Vaughan tocando una gran versión de un tema de Jimi Hendrix "Little Wings". Espero que lo disfruten.





Saludos!

domingo, 3 de enero de 2010

Google AppEngine: Protegiendo el contenido web.

En un post anterior vimos como utilizar las cuentas de google para hacer login y logout en app engine. Ahora veremos una de las opciones para proteger contenido en nuestra aplicación, mediante la definición de reglas declarativas en el archivo web.xml. Para una referencia completa de las cosas que podemos hacer en el web.xml para app engine, ver el siguiente enlace.

AppEngine provee una forma estándar (llamando a estándar a compatible con JAAS) para proteger recursos declarativamente. Por ejemplo en la aplicación del appspot de este sitio se definió:

    <security-constraint>
<web-resource-collection>
<url-pattern>/seguro/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>

Diciendo que lo que hay dentro de la carpeta "/seguro/" puede ser sólamente accedido por el rol "*".
AppEngine nos provee 2 roles distintos para nuestra aplicación:
  • El rol de cuenta de google: "*"
  • El rol de administrador: "admin"
El primero se aplica a cualquier persona logueada con su cuenta de google, y el segundo sólo a aquellas cuentas de google que definimos en la configuración de la aplicación como "admin".

Esta definición resulta suficiente para proteger cualquier contenido en nuestra aplicación, sin embargo cuando trabajamos con GWT, las consideraciones son un poco distintas, ya que debemos por un lado proveer una lógica que oculte o deshabilite opciones que no son accesibles y, debido a que se trata de código en el cliente, debemos proteger las llamadas remotas.

El escenario ideal para proteger las llamadas remotas es el de los servlets con programación orientada a aspectos o AOP y posiblemente anotaciones para asegurar métodos en forma declarativa. En un post futuro investigaremos estas posibilidades y utilizaremos filtros, algo realmente poderoso, para armar la seguridad de la forma menos trabajosa.

Saludos!

Google AppEngine: Acceso a las cuentas de google.

Una de las facilidades que nos provee Google AppEngine es la de acceder a las cuentas de google. He estado experimentando un poco con esto y puedo remarcar los siguientes puntos:
  • El acceso a la info del usuario logueado se realiza a través del mecanismo estándar de JAAS.
  • Pueden protegerse urls del sitio mediante el mecanismo estándar de la web tier, esto es definiéndolas en el archivo web.xml.
  • El mecanismo de login y logout es no estándar.
En este post demostraré el uso que le he dado a esta funcionalidad en el appspot del sitio. En próximos post demostraré alternativas para proteger urls del sitio.

El ejemplo es la implementación un servicio RPC de GWT. Primero echemosle una mirada a los import.
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import appspot.client.CommonService;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import javax.servlet.http.HttpServletRequest;
Lo primero que vemos entonces son los import comunes de GWT para los servicios RPC, también vemos importada la interfaz necesaria para que la magia funcione "CommonService" (ese nombre lo elegí yo). Luego vemos las clases de google para acceder a sus cuentas, la "UserService" y "UserServiceFactory", de los nombres mismos ya se puede inferir el uso.

Lo próximo que veremos es la implementación de la clase de servicio, en la cual accedemos a las api.


public class CommonServiceImpl extends RemoteServiceServlet
implements CommonService {

@Override
public String getUserMail() {

UserService us = UserServiceFactory.getUserService();
if (!us.isUserLoggedIn()) {
return null;
}

HttpServletRequest req = getThreadLocalRequest();
String name = req.getUserPrincipal().getName();
return name;
}

@Override
public String getLoginUrl(String baseUrl) {
UserService us = UserServiceFactory.getUserService();
return us.createLoginURL(baseUrl);
}

@Override
public String getLogoutUrl(String baseUrl) {
UserService us = UserServiceFactory.getUserService();
return us.createLogoutURL(baseUrl);
}
}

Vemos que nuestro servicio tiene 3 métodos:
  • Obtener el usuario logueado.
  • Generar una URL que nos llevará a una pantalla de login.
  • Generar una URL que nos deslogueará del servicio.
En el primer método utilizamos el userService para preguntar si el usuario se encuentra logueado. Esta es una manera no estándar, pero realmente simpática y prolija.
Luego utilizamos una forma estándar para obtener el "User Principal", el cual traducido del lenguaje JAAS, es el usuario logueado.

Los métodos de generar urls son prácticamente iguales, en uno pedimos de una manera no estándar que nos entreguen una url de la página de login diciendo también la url a la cual queremos ir despues de estar logueados. Esto es realmente una ventaja comparado con la forma estándar en la cual definimos en web.xml un formulario de login al cual llegamos tratando de alcanzar una url no permitida, ya que la lógica de navegación para el login debe ser inferida y no puede leerse del propio código. Con eso le damos fin a nuestra demostración. Espero que haya sido de utilidad.

Saludos!