Introducción a Apache James
0. Índice de contenidos.
- 1. Introducción.
- 2. Entorno.
- 3. ¿Qué es Apache James?.
- 4. Instalación.
- 5. Mailets y Matchers.
- 6. Ejemplo de Mailet y Matcher personalizado.
- 7. Conclusiones.
1. Introducción
En este tutorial vamos a ver una pequeña introducción de Apache James, qué es y en qué nos puede ayudar.
Mostraremos una pequeña guía de cómo configurar Apache James y jugaremos con él creando unos componentes necesarios como son los Mailets y los Matchers.
Este pequeño artículo no pretende ser una guía detallada de cómo configurar ni utilizar James sino una pequeña introducción a los aspectos más generales e importantes de este servidor.
2. Entorno.
El tutorial está escrito usando el siguiente entorno:
- Hardware: Portátil MacBook’ (2.4 GHz Intel Core 2 Duo).
- Sistema Operativo: Mac OS X Snow Leopard 10.6.6
- JDK 1.6.0_22
- Apache James 2.3.2
3. ¿Qué es Apache James?.
Apache James es un proyecto de la fundación Apache que porporciona un servidor de correo basado íntegramente en Java.
La elección de James como servidor de correo para nuestras aplicaciones nos dota de una gran flexibilidad a la hora de tratar con los correos que mueve nuestro dominio, permitiendo tener un control total sobre lo que está pasando en nuestro servidor de correo como por ejemplo el decidir cuáles són las reglas a aplicar sobre e-mails que recibe el servidor, monitorizar todo el flujo de correos, decidir cuáles deberían prohibirse, poder definir nuestra propia política de anti-spam, entre otras.
4. Instalación.
Para instalar James hay que ir a esta página y descargarse el binario (a la hora de escribir este tutorial, la versión estable de James era la 2.3.2).
El siguiente paso es descomprimir el fichero en algún directorio de vuestra máquina y deberíais ver una estructura de directorios como la que se muestra a continuación:
Una vez tenemos instalado James, el siguiente paso es arrancarlo para empezar a trabajar con él. Para ello hay que dirigirse al directorio bin y ejecutar el archivo run.sh o run.bat en función del sistema operativo. Una vez arrancado se debería ver esto:
Desconozco cómo es en Windows pero sobre plataformas Unix tendréis que arrancar James como root ya que por defecto se trabaja con los puertos 110, 22 y 119, puertos reservados para el usuario root al ser inferiores a 1024. Para cambiar estos puertos hay que dirigirse al fichero de configuración principal que se encuentra en james-2.3.2/apps/james/SAR-INF/config.xml.
5. Mailets y Matchers
Hay dos pilares fundamentales a entender dentro de Apache James, los matchers y los mailets componentes sobre los que gira en gran parte todo el servidor.
¿Qué es un Matcher?
Un matcher es un agente de seguridad, permite a James decidir si un e-mail debe ser procesado o si por el contrario no se debe permitir su procesamiento posterior. Un matcher es el segurata del sistema.
James proporciona una serie de matchers programados por defecto. Se pueden ver aquí. Por ejemplo si somos los administradores de una lista de correo de adictosaltrabajo.com podemos definir el matcher SubjectStartsWith para especificarle a James que todos esos correos que no tienen en el asunto «Adictos al trabajo:» que los envie a la basura ya que no cumplen con las directrices de la lista. Por el contrario si el correo empieza con ese texto, el matcher dejará pasar el correo para poder ser tratado en fases posteriores.
¿Qué es un Mailet?
Un mailet es un agente para procesar e-mails.
Si un servlet es invocado cuando una conexión HTTP se lanza contra un contenedor de servlets, en este caso y salvando las distancias un mailet es ejecutado cuando entra un e-mail dentro de James para ser procesado. Antes de llegar al mailet, el correo debe haber pasado por los «seguratas» de James, los matchers.
Todo mailet tiene un ciclo de vida establecido, se inicia, se procesa y se destruye mediante los métodos:
init(MailetConfig config) service(Mail mail) destroy()
Apache James proporciona por defecto una serie de mailets para ser utilizados dentro del contenedor de correos como por ejemplo un mailet para procesar un e-mail que entra al contenedor de tal forma que devuelva el mismo correo pero sólo la parte que contiene texto eliminándolo.
Apache James proporciona por defecto una serie de mailets que se pueden ver aquí.
Por ejemplo y para intentar de acabar de asimilar el concepto de mailet, James proporciona un mailet llamado ReplaceContent que permite reemplazar cadenas de texto del asunto y/o contenido mediante expresiones regulares.
Un ejemplo de este mailet podra ser utilizado para un servidor de correos de una red social para niños. El jefazo de la red social no quiere que haya una sola palabra malsonante en los correos así que configura James para que substituya todas las palabrotas por asteriscos.
A grandes rasgos el flujo sería:
- 1 – Niño A envía correo a usuario niño B.
- 2 – James recibe correo de niño A.
- 3 – James dirige esos correos hacia los matchers (para simplificar, sólo hay uno y deja pasar a todos los correos).
- 4 – James observa que el e-mail cumple con todos los matchers así que les permite continuar.
- 5 – James ejecuta el mailet configurado para esos matchers.
- 5.1 – James modifica todas las palabrotas que niño A le escribirá en el e-mail a niño B.
- 6 – James deja proceder con el correo.
- 7 – Niño B ve asteriscos.
6. Ejemplo de Mailet y Matcher personalizado.
En el punto anterior hemos visto por encima que James nos proporciona una buena lista de mailets y matchers que se adaptan bastante bien a muchos escenarios. No obstante el conjunto de posibles escenarios es imilitado así que James nos proporciona una forma de crear nustros propios mailets y matchers.
Como ejemplo vamos a poner un escenario en el que en una empresa existen dos correos de atención al cliente, cuenta1@empresa.com y cuenta2@empresa.com. Si bien puede resultar extraño nos será bastante útil para mostrar el ejemplo. La idea es que el jefe quiere que cuando se estén enviando (por X razones) más correos a una cuenta en particular, que le envie un correo avisándole de este desbalanceo de trabajo para poner solución.
Lo primero que vamos a hacer es crear un matcher que sólo invoque el mailet que posteriormente vamos a escribir sólo y exclusivamente si las direcciones a las que se dirige el correo son cuenta1@empresa.com y cuenta2@empresa.com.
Para crear un matcher personalizado sólo hay que crear una clase que implemente la interfaz Matcher.
public BlockEmailMatcher implements Matcher {
El código para decidir cuales són las direcciones de correo que queremos dejar pasar y enviar hacia un mailet va dentro del método match(Mail mail).
public Collection match(Mail mail) throws MessagingException { Collectionrecipients = new ArrayList (); Iterator it = mail.getRecipients().iterator(); while(it.hasNext()) { MailAddress to = (MailAddress)it.next(); if(customerService.validEmail(to)) { recipients.add(to); } } return recipients; }
customerService es una instancia de un objecto que nos permite conocer si la dirección a la que se dirige el correo es cuenta1@empresa.com o cuenta2@empresa.com. Las direcciones que estén dentro de la colección de devolvemos van a ser recibidas por el mailet que se asocia a este matcher así que si en un matcher lo que queremos es filtrar, tenemos que devolver una colección vacía.
Para crear un mailet personalizado sólo hay que crear una clase que implemente la interfaz Mailet.
public class BlockEmailMailet implements Mailet {
Anteriormente hemos comentado que un mailet ejecuta una lógica cuando se recibe el contenedor recibe un correo y pasa el matcher. Esta lógica está contenida dentro del método service(Mail mail):
@Override public void service(Mail mail) throws MessagingException { MailAddress to = null; Iteratorit = mail.getRecipients().iterator(); while(it.hasNext()) { to = (MailAddress)it.next(); if(workers.uncompensatedWork(to)) { mailetConfig.getMailetContext().log("Too much work! sending an email to the manager"); mail.send(UNBALANCED_WORK); } } }
Cuando llega un correo se ejecuta el método de arriba y si hay una desbalanza de trabajo entre los trabajadores responsables de la atención al cliente, se envia un correo al gerente.
mail es una instancia de un objecto para enviar correos.
workers es una instancia de un objeto que nos devuelve true o false si un trabajador está más ocioso que otro.
Para configurar que BlockEmailMailet debe estar relacionado con BlockEmailMatcher hay que añadir esta configuración en james-2.3.2/apps/james/SAR-INF/config.xml.
Cuando se reciba un correo se invocará BlockEmailMatcher conjuntamente con todos los matchers configurados y si pasa ese matcher concreto, se ejecutará el código escrito en BlockEmailMailet.
7. Conclusiones.
Apache James nos brinda un interesante servidor de correos para poder crear aplicaciones que procesen los correos electrónicos a nuestra entera disposición trabajando en Java.
Un saludo.
Jordi
Que alegría ver a una persona de Jobsket publicando cositas… seguro que interesantes.
Buen dia
Me podria ayudar a echar a andar un servidor James. Ya llego hasta la parte de hecharlo a andar. Pero, despues que este funcionando que? Como me conecto a el? Como envio correos?
Saludos
Que tutorial tan incompleto, de verdad se nota que estabas como de afán!!! ponerle ganas a esto hombre ehhh, a propósito ya salió la versión 3.0. https://james.apache.org/