Mostrando entradas con la etiqueta Tecnología. Mostrar todas las entradas
Mostrando entradas con la etiqueta Tecnología. Mostrar todas las entradas

viernes, 16 de septiembre de 2011

Y... bueno ya es hora de venderme

Ya llevo tiempo pensando en la poca publicidad que doy al trabajo que realizo. Y analizando el trabajo de otras personas mucho más famosas que yo y cuya trayectoria es sobradamente conocida, hoy me encuentro con muy poca autoestima, así es que necesito recordarme algunas cosas, que me hacen pensar en lo banal de esas reputaciones que en muchos casos se deben más al éxito comercial de los proyectos en los que se han implicado que al mérito técnico, al buen análisis y diseño, o a la elección de la tecnología más adecuada.

Desde que comencé con la programacion en el sector privado allá por el año 2002 o desde que cree una red social para mi proyecto fin de carrera en PHP allá por el año 2003, y tras el éxito comercial de este tipo de portales al cual no supe dar salida en su momento, la enumeración de trabajos que he realizado en "background" sin importarme que se supiera que mi mano está ahí ha sido innumerable.

Soy inquieto y quiero aprender más siempre. Por eso estoy seguro de que siempre tendré actitud y potencial para cumplir con cualquiera de los objetivos que se me plantean. Y lo he demostrado.

He desarrollado mis habilidades haciendo uso de varios conocidos frameworks, como struts e hibernate en Java y con el desarrollo frameworks propios que siempre me han resultado más útiles, escalables y sencillos, quedando demostrado en los desarrollos que hoy en día andan... por ahí...
y que por otro lado me abren las puertas para que tras un largo periodo, tenga acceso a dirigir proyectos y por ejemplo, analizar y codificar un gestor de trámites administrativos que incluye el diseño de cualquier procedimiento con la administración y su adecuación a la legalidad sobre la e-administración. Un proyecto sin precedentes que la Junta de Andalucía seleccionó para incluir en su repositorio de aplicaciones disponibles para su uso como software libre para cualquier administración en esta tierra.

El trabajo que he realizado pasa por el análisis y desarrollo para empresas en distintos sectores que también incluyen sectores como la aeronáutica, la formación y el e-learning, pero también he dirigido procesos de certificación de calidad y realizado labores de consultoría.

Entre muchos otros trabajos se me ocurre también destacar el proyecto "Dentro Video" para Joomla, con la investigación y desarrollo de su sistema de almacenamiento y taggeo, el análisis y desarrollo de un sistema de grabación televisiva y de analizar, diseñar y codificar la primera escuela de poker en Internet que reproduce, almacena y auto-corrige las manos subidas de cientos de miles de jugadores en internet, con un proceso de minería de datos que en su conjunto, conforma una de las herramientas de formación y análisis del poker mas novedosas en el mundo.

Y todo bajo la potencia y escalabilidad del framework que desarrollé hace ya algunos años con el que además me he lanzado al universo del "reality mining" con City Analytics, un sistema que en tiempo real ofrece información sobre el movimiento de las personas en las ciudades, integrándome con todo tipo de clientes en PHP, Ruby o Python y además estando a cargo de los sistemas que soportan tal cantidad de datos.

Y tras tanto desarrollo y después de haber visto como "programadores" (según ellos) de toda índole mienten descaradamente a costa de otros incautos como yo, me encuentro que no es suficiente porque nunca dije "Esto es mío", por que nunca dije "Esto lo hice yo".

Pero ya va llegando el momento. Y sobre todo después de estudiar en la universidad, donde ahora me encuentro que no sirvió de nada, puesto que el gobierno reconocerá un título a todos aquellos que se aprovecharon de mi trabajo, y que puedan acreditar que llevan 10 años en este trabajo. Así, por el intrusismo laboral y por listos, ahora, perfectos inútiles podrán conseguir un título. Debí ponerme a trabajar sin estudiar, puesto que ahora, tendría más dinero y el título que tanto trabajo me costó conseguir. Desde luego esta es la mejor forma de fomentar la ignorancia y la "cutrez", en lugar de potenciar la calidad, que es lo único que le queda al mundo occidental.

viernes, 29 de julio de 2011

En un periquete

Tanto tiempo sin escribir que ni recuerdo por donde iba... y es que han sido casi cuatro meses de infarto.

Por un lado el trabajo. En Ciudad 2020 no paramos, siempre tenemos nuevos retos y nuevos proyectos. He estado integrándome con todo tipo de clientes y aplicaciones que beben de nuestra API, y además en Mayo terminé con el desarrollo del mapa de movilidad de Córdoba. Un proyecto muy interesante en el que he aprendido más de la API de Google Maps V3 de lo que jamás pensé que me haría falta.... jejeje. Encontré especialmente interesante el sistema de InfoWindows y el sistema que dibuja el HeatMap, que se complementa con java.awt.Graphics2D en el servidor.

Y lo hemos presentado al mundo en el "Living Labs Global" en Estocolmo, donde estuve en un Workshop group con Lewis Carl de Oracle debatiendo sobre "Cloud Computing".



Por otro lado City Analytics sigue creciendo y madurando, de forma que hemos incluido muchas mejoras en el rendimiento, tras algún que otro traspiés, hasta que hemos liberado la versión 1.9 del cliente. Esto unido a nuevos servicios como el Checkin Físico y otras novedades que incorporaremos en breve me ha tenido bastante ocupado.

Y por otro lado, hay algo que se ha hecho un hueco en mi vida, y que está creciendo de forma que casi asusta. Pero ya no hay quien lo pare. No hay palabras para esto y solo aquellos que lo han sentido lo pueden entender. Me viene al pelo esa frase de la canción de Los Suaves que dice que "hay cosas que solo se dicen con silencio y yo callándome te las digo". Mi hija vino al mundo el día 9 de abril.

lunes, 28 de marzo de 2011

Optimización de MySql InnoDB en un servidor Linux

Tras un arduo proceso de investigación y documentación, voy a describir el proceso a seguir para configurar un servidor MySql para producción. Las bases consultadas no son otras que la documentación oficial en dev.mysql.com y mysqlperformanceblog.com.

En la configuración de un servidor debes pensar en una instalación que tenga un rendimiento acorde con lo que se necesita, empezando por la instalación del sistema operativo. Como es de imaginar principalmente MySql realiza tareas pesadas sobre los discos duros, por lo tanto la elección de discos duros con bajos tiempos de búsqueda es importante pero también es importante si tienes varios discos, optar por usar RAID 0 para unirlos, lo cual afecta bastante al rendimiento de las búsquedas.

Después será necesario revisar la implementación y el diseño de tu base de datos. Respecto al diseño no contaré nada puesto que depende de la aplicación/es que hagan uso del Data Source con MySql, pero respecto a la implementación si que hay un par de cuestiones a tener en cuenta:
  • Manten el tamaño de los campos de tu BBDD lo más pequeño posible. Si puedes usar mediumint en lugar de bigint hazlo, y a colación e igual de importante es que:
  • No utilices campos `varchar`. Y si lo necesitas, al final de la tabla. Dependiendo de tus necesidades por supuesto, pero ten en cuenta que en su lugar puedes usar el tipo `char`. Un tamaño variable para las cadenas ahorra espacio en disco pero un tamaño fijo permite un acceso más rápido a los datos puesto que no hay que calcular la longitud del registro variable como ocurre cuando tenemos un `varchar` y saltamos al siguiente registro. InnoDB realiza algunas optimizaciones por ejemplo convirtiendo `varchar` de tamaño menor de 4 en `char`, pero es deseable que calcules la longitud máxima de un campo y crees campos de tamaño `fixed`. Dentro de poco cuando regalen TeraBytes con las cajas de galletas, esta pérdida de espacio con registros `fixed` no será tan importante como el rendimiento de las consultas a tu servidor... ;)
  • Crea solo los índices que necesitas y elimina índices duplicados. Los índices benefician el proceso de lectura pero pueden complicar el de escritura, así que debes tener cuidado con esto. También ocurre que borras y creas una tabla un varias veces cambiando el script, modificando... y al final, revisando te das cuenta de que tienes un índice duplicado. Si el tamaño de tu tabla no es muy grande, el gasto en memoria puede no ser demasiado, pero he llegado a reducir en cerca de 3 Gb el tamaño de una tabla tan solo descubriendo y eliminando un par de índices duplicados.

Una vez que hayas revisado esto lo deseable es afinar el rendimiento de la ejecución de MySql. Los parámetros más importantes son (para InnoDB):

  • innodb_data_home_dir ( =/var/lib/mysql): Es el lugar donde InnoDB almacenará la información (anteponiéndolo a innodb_data_file_path en caso de existir) así como los ficheros de registro. Asegúrate que apunta a tus discos en RAID 0.
  • innodb_data_file_path | innodb_file_per_table: Con estos parámetros configuras como se almacenan tus datos y donde. Si especificas innodb_file_per_table, indicas a MySql que guarde los datos de cada tabla en un fichero distinto. Esto es beneficioso si tienes en mente ampliaciones y/o migraciones.
  • innodb_buffer_pool_size: El tamaño que ocupa en memoria el almacenamiento intermedio de datos. Cuanto mayor es este valor, menor es la cantidad de operaciones de lectura/escritura en disco. El valor adecuado para un servidor dedicado solo a MySql debería permitir la ejecución del sistema operativo sin problemas. Ten en cuenta que a este tamaño se suma el del parámetro key_buffer_size en el motor MyISAM. Desde la documentación oficial de MySql especifican un 80% de la memoria del ordenador, pero con 64Gb de RAM tendríamos 12 Gb para el SO... es mucho ¿no?
  • innodb_log_file_size: Es el tamaño de los ficheros de registro de InnoDB. Pueden existir varios y la suma de sus tamaños no puede exceder los 4Gb. Un tamaño mayor reduce las operaciones de lectura/escritura en disco, así que este parámetro también es importante. Una regla para fijar este valor se basa en darle el 25% del tamaño especificado en innodb_buffer_pool_size. Ten en cuenta que cada vez que quieras cambiar el tamaño de los ficheros de registro debes fijarte en que probablemente ya existan así es que tendrás que:
    1. Parar el servidor,
    2. Hacer copia de seguridad de los ficheros de log. Normalmente ib_logifle0 e ib_logfile1 en /var/lib/mysql renombrados a ib_logfile0.BAK e ib_logfile1.BAK. En caso de pánico y horror puedes restaurarlos.
    3. Borrar los originales (ib_logfile0 e ib_logfile1),
    4. Especificar el nuevo tamaño, e
    5. Iniciar MySql
  • innodb_log_buffer_size: Es el tamaño del almacenamiento intermedio en los ficheros de registros, por lo tanto valores altos también reducen el número de operaciones de lectura/escritura. Aún así el tamaño de esta variable (evidentemente siempre menor que innodb_log_file_size) se establece como razonable entre 8 y 16 Mb ya que este buffer se vuelca forzosamente cada segundo, así que puede no ser necesario un tamaño mayor y si que sería un gasto de memoria.
  • innodb_flush_log_at_trx_commit: Este parámetro controla cuando se vuelcan los datos del buffer en los ficheros de registros. Este volcado se realiza cada segundo forzosamente pero puede hacerse más a menudo. El valor por defecto de 1, indica que este volcado se realiza tras un commit. Un valor de 2 sería cada 2 commit, o cada segúndo, lo que ocurra antes. De esta forma un valor de 2 reduce las operaciones de E/S en disco pero podríamos perder un segundo de transacciones en caso de error del sistema. Yo pongo 2... ;)
  • innodb_flush_method: Indica la forma de volcado de los ficheros de registros y datos. Si está disponible, con la opción O_DIRECT evitamos el uso de memoria swap y así MySql vuelca estos ficheros directamente en memoria física evitando consumir ancho de banda entre la memoria y la CPU por las copias de la cache del kernel y del espacio de memoria del usuario.

Pues con esto espero haber arrojado algo más de información sobre los parámetros más importantes, aunque evidentemente me dejo mucho en el tintero, pero para mí estas son las cuestiones más importantes. Suerte!!

lunes, 20 de diciembre de 2010

Comprimiendo Streams en GZIP con java.util.zip

Bueno, pues algo muy sencillo pero que espero que facilite la vida a más de uno. La cuestión es que tienes "algo" que puede ser en el caso más sencillo una cadena, y que quieres enviar por red por ejemplo, o tus propias movidas.

Como decía un gran sabio en una conferencia sobre protocolos cuando hacían debates sobre XML-RPC y REST...

"En ocasiones uso sockets."

Pues bien... aún así estas dos funciones aumentarían la velocidad de usar solo sockets, y podrían en un determinado momento ayudaros mucho (como a mí cuando las terminé) para optimizar lo que enviéis... como os dé la gana.
Aunque se pueden usar otros algoritmos de compresión, GZIP es el de mejor relación de compresión/computación, y no tienes que añadir ninguna librería. Te permitirán aumentar la eficiencia en el envío o almacenamiento bastante así que ahí van:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
...


/**
* Obtiene el array de bytes comprimido a partir de otro array de bytes
* que se quiere comprimir.
* @param file los datos descomprimidos
* @return los datos comprimidos.
* @throws IOException de vez en cuando
*/
public byte[] comprimirGZIP(byte[] file) throws IOException {
ByteArrayOutputStream gzdata = new ByteArrayOutputStream();
GZIPOutputStream gzipper = new GZIPOutputStream(gzdata);
ByteArrayInputStream data = new ByteArrayInputStream(file);
byte[] readed = new byte[1024];
int actual = 1;
while ((actual = data.read(readed)) > 0) {
gzipper.write(readed, 0, actual);
}
gzipper.finish();
data.close();
byte[] compressed = gzdata.toByteArray();
gzdata.close();
return compressed;
}

/**
* Obtiene el array de bytes descomprimido a partir de otro array de bytes
* comprimido
* @param file los datos comprimidos
* @return los datos descomprimidos.
* @throws IOException de vez en cuando
*/
public byte[] descomprimirGZIP(byte[] file) throws IOException {
ByteArrayInputStream gzdata = new ByteArrayInputStream(file);
GZIPInputStream gunzipper = new GZIPInputStream(gzdata, file.length);
ByteArrayOutputStream data = new ByteArrayOutputStream();
byte[] readed = new byte[1024];
int actual = 1;
while ((actual = gunzipper.read(readed)) > 0) {
data.write(readed, 0, actual);
}
gzdata.close();
gunzipper.close();
byte[] returndata = data.toByteArray();
csvdata.close();
return returndata;
}

domingo, 28 de noviembre de 2010

Integrar el pago electrónico con paypal en java

Es increíble lo complicado que a veces puede resultar encontrar información sencilla sobre algo concreto. A la hora de la integración de una aplicación con sistemas de pago electrónico puedes encontrar algunos de los mejores ejemplos. Lo que voy a explicar es producto de un número demasiado elevado de horas buscando, leyendo, consultando y quebrándome la cabeza.

Y no solo con el caso específico de PayPal, sino con el resto de plataformas de pago con las que me he encontrado. Estoy pensando seriamente en crear un grupo en facebook "En contra de las explicaciones ambiguas para integrar plataformas de pago".

Bueno pues lo primero es saber si es complicado lo que tienes que hacer, porque lo que voy a contar es un pago estandar, es decir, una vez que en tu app ya sabes la cantidad que hay que pagar, quieres que se haga. Si quieres hacer pagos o gestionar tus cobros, o cosas más complejas con la interfaz SOAP, no es este tu artículo, jeje... Lo que vas a encontrar es lo que llaman:

  • Pago Express
  • Interfaz para NVP (abreviado de name-value pair)
  • Pago Estándar

Siempre hay un entorno de pruebas, como ya esperabas, y que funcionará exactamente igual que en el entorno real. Esta es una de las diferencias (entre otras) con plataformas con las que he trabajado y PayPal.

En esta última, el proceso que en principio creemos sencillo, que es el de obtener un número de tarjeta ficticio que sea aceptado por la validación de la tarjeta en la plataforma de pruebas, me implicó crear una cuenta ficticia de cliente en Paypal Sandbox y asociarle tarjetas.

Después de mucho clickar y urgar por el sandbox, trás intentar comprender que tipo de pago quiero realizar (..ufff) o ver mil veces el esquema de pago, tienes que tener una cuenta de empresa (o también llamado comerciante) e ir al menú "Perfil" para encontrar lo que buscas.
  • Preferencias de notificación de pago instantánea (IPN)
  • Configuración de pago codificado

1. Preferencias de notificación de pago instantánea IPN

En la primera opción tienes que indicar la url a la que se notifica el pago mediante petición POST. Esto quiere decir que cuando el pago se confirma, desde paypal se hará una solicitud a esa url que pongas, e incluirá además de una copia de los valores en la petición que mandamos desde nuestra web (desde el navegador del usuario) algunos parámetros más como el identificador de operación, que es el que a ti te interesa. ¿Problemas con el IPN? Se pueden deber a varios factores:

  • El pago no se confirma: Esto ocurre con cantidades elevadas, paypal desde hace poco está obligado a retener las cantidades elevadas (no recuerdo ahora el intervalo exacto) y las contrasta. Tu tendrás que acceder a tu cuenta de paypal (del sandbox) y confirmar el pago manualmente. Probablemente ya te habrá caducado la sesión, y tendrás que tirarte un rato logeandote de nuevo, pero de tanto hacerlo, tienes la contraseña grabada a fuego en tu cerebro... ¿verdad? :P
  • La url de respuesta no es correcta: Claro suele pasar... cámbiala

2. Configuración de pago codificado

En la segunda opción, configuras el certificado que vas a usar para "firmar un botón". Esta impresionante acción, como todas, al final no es para tanto y no es más que tomar una cadena con la información del pago, firmarla, y añadir el texto de la firma (...en PEM) a un formulario que se dirija a Paypal y que los navegantes presionan en tu página cuando quieren realizar el pago. Y con esto pues ya está, ahora:
  • Te descargas El SDK para java, descomprimes e incluyes las librerías en tu aplicación en /WEB-INF/lib
  • Descárgate todos los jars de las librerías criptográficas bouncycastle latest releases e incluyes las librerías en tu aplicación en /WEB-INF/lib
  • Creas tus certificados para firmar e identificarte con paypal: Para esto necesitas instalar OpenSSL (en ubuntu con "sudo apt-get install openssl"... en windows... no lo sé...) y ejecutar:

    #Generas la clave privada, el CSR
    openssl genrsa -out prvkey.pem 1024
    #La auto firmas y obtienes un certificado público
    openssl req -new -key prvkey.pem -x509 -days 365 -out pubcert.pem
    #Generas un almacen de certificados pkcs12 con ellos
    openssl pkcs12 -export -inkey prvkey.pem -in pubcert.pem -out prvkey.p12


    Después de todo esto te aparecen un montón de ficheros de los cuales solo te hace falta el almacén de certificados prvkey.p12 y el certificado de paypal que debes descargarlo desde paypal en la opción de "Configuración de pago codificado".

Pues nada, ten a buen recaudo la contraseña para el acceso al almacen de certificados y el archivo p12 por que ahora viene cuando se usa.

Realización del pago, datos del pago y firma

Bueno pues ya estás en tu aplicación y estás desarrollando la parte en la que se realiza el pago, entonces, tu objetivo va a ser crear una página donde se indique al cliente lo que va a pagar y se muestre un botón que ponga "Pagar con Paypal". El código HTML del formulario lo pones tú, pero asegúrate de que tienes dos campos:

<input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="encrypted" value="<%= signedPaymentStr %>" />


que se envían a la url que te pasan desde paypal (algo de documentación tendrás que leer).

Los datos del pago van en la cadena firmada del campo encrypted, y básicamente tendrás que rellenarlos creando una cadena con algunos parámetros. Aquí os dejo el código de un metodito que devuelve directamente la cadena que buscamos. Cópialo, pégalo y míra el Javadoc, te resultará fácil. Ten en cuenta que el pago está configurado para EUROS!!...



import com.paypal.wpstoolkit.util.PPCrypto;
import java.util.Properties;
import org.apache.log4j.Logger;

.....
.....



/**
*
* Obtiene la cadena del botón encriptada para una compra. Una cadena de
* ejemplo sería:
*
* cert_id=...
* cmd=_xclick
* business=....
* item_name=Lorem Ipsum Dolor sit amet...
* item_number=1234
* custom=sc-id-789
* amount=500.00
* currency_code=EUR
* tax=41.25
* shipping=20.00
* address_override=1
* address1=Calle inventada
* city=Ciudad
* state=Estado
* zip=23452345
* country=ES
* no_note=1
* cancel_return=http://url.de.retorno
* @param paymentData Variables adicionales que se quieran adjuntar.
* @param concepto Descripción de concepto por el que se va a pagar.
* @param codigoVenta Identificador de la venta
* @param cantidad Cantidad en euros que se va a cobrar
* @param impuesto Cantidad que se va a cobrar de impuestos
* @param direccion Dirección del pagador
* @param numero numero de la direccion postal
* @param cp Codigo postal
* @param localidad Localidad de la dirección postal
* @param pais País de la dirección postal
* @param nombre Nombre del pagador
* @param apellidos Apellidos del pagador
* @param pruebas Booleano que indica si se dirigirá al entorno de pruebas o no
* @return cadena de la firma de los datos.
* @throws Exception
*/
public String getButtonEncryptionValue(String paymentData,
String concepto, String codigoVenta, Float cantidad, Float impuesto,
String direccion, String numero, String piso, String puerta,
String cp, String localidad, String pais, String nombre,
String apellidos, String email, Boolean pruebas) throws Exception {

Properties oProps = new Properties();
ClassLoader oCL = Thread.currentThread().getContextClassLoader();

InputStream oIStr = oCL.
getResourceAsStream("archivodeconfiguracionenclasspathquesiempreexiste.properties");
oProperties.load(oIStr);
oIStr.close();

String env = ".sandbox";
if (!pruebas) {
env = "";
}

String signedStr = null;

String _keyPass = "password_que_tienes_que_poner_bien";
String user = "userquetienesqueponerbien";
String certId = oProps.getProperty("propiedad_con_el_valor_que_te_da_paypal_al_registrarte");
String returnURL = oProps.getProperty("propiedad_url_de_vuelta_en_navegador_despues_de_pagar");
String returnCURL = oProps.getProperty("propieda_de_la_url_si_cancela_el_pago");
if (piso == null) {
piso = "";
}
if (puerta == null) {
puerta = "";
}
if (_data == null) {
_data = "";
}
if (numero != null && numero.length() > 0) {
direccion += " nº " + numero;
}
if (piso != null && piso.length() > 0) {
direccion += " - " + piso + "º";
}
if (puerta != null && puerta.length() > 0) {
direccion += " " + puerta;
}

paymentData += "cert_id=" + certId + ","
+"item_name=" + concepto.replaceAll(",", "") + ","
+"item_number=" + codigoVenta + ","
+"amount=" + String.format("%1.2f", cantidad).replaceAll(",", ".") + ","
+"tax=" + String.format("%1.2f", impuesto).replaceAll(",", ".") + ","
+"address_override=1,"
+"address1=" + direccion.replaceAll(",", "") + ","
+"city=" + localidad + ","
+"zip=" + cp + ","
+"country=" + pais + ","
+"first_name=" + nombre + ","
+"last_name=" + apellidos + ","
+"payer_email=" + email + ","
+"cmd=_xclick,"
+"business=" + user + ","
+"currency_code=EUR,"
+"lc=" + pais + ","
+"cbt=Volver a la página,"
+"return=" + returnURL + ","
+"cancel_return=" + returnCURL + "";

logger.info("Encoding data: " + paymentData);

paymentData = paymentData.replace(',', '\n');
try {
signedStr = new String(PPCrypto.getButtonEncryptionValue(paymentData.getBytes("UTF-8"),
oProps.getProperty("ruta_al_archivo_p12"),
oProps.getProperty("ruta_al_certificado_de_paypal"),
_keyPass));
} catch (Exception ex) {
logger.error("Excepcion firmando: " + ex.getMessage());
}
return signedStr;
}

domingo, 6 de junio de 2010

El usuario de una petición WS con Axis y WSS4J

Hace tiempo que andaba buscando la manera de obtener las credenciales de identificación enviadas en una petición a un Web Service.

El problema viene dado por la necesidad de asegurar el acceso a los métodos que se ofrecen por XML-RPC y posteriormente en su implementación, identificar al usuario, pero resulta que Axis 1.4 (en su configuración más.. cómoda), realiza el despliegue de un servicio a partir de un POJO especificado en el wsdd, y entonces ¿Como podemos hacer referencia al contexto del mensaje recibido?

Pues todo viene a partir de la clase MessageContext de Axis. En cualquier momento de una petición, está disponible la llamada a dicho objeto, y a su método estático getCurrentContext mediante el cual tendremos acceso al mensaje objeto de la petición realizada.

La identificación del usuario ya se realiza por parte de WSS4J, y ahora nosotros queremos asociar los datos enviados al usuario que se identificó, de forma que en estos POJO's podremos escribir el siguiente código:


String username = null;
Iterator<SOAPHeaderElement> oItHeaderEnv = MessageContext.
        getCurrentContext().getMessage().getSOAPHeader().
        examineAllHeaderElements();
while (oItHeaderEnv.hasNext()) {
    Iterator<MessageElement> oItHeaderElems = oItHeaderEnv.next().
         getChildElements();
    while (oItHeaderElems.hasNext()) {
        Iterator<MessageElement> oItParams = oItHeaderElems.next().
            getChildElements();
        while (oItParams.hasNext()) {
            MessageElement oWSSParam = oItParams.next();
            if("Username".equals(oWSSParam.getName())) {
                username = oWSSParam.getValue().trim();
                break;
            }
        }
    }
}


Este código nos permitirá acceder al nombre de usuario enviado, o a cualquier otro parámetro enviado en la cabecera Security.

Otra de las opciónes, es la implementación de sesiones de Axis, ya que en la misma PasswordCallbackClass del Handler de WSS4J, podríamos implementar el inicio de la sesión, y después recuperarla en el método ofrecido por XML-RPC, previa configuración del manejador de sesiones de Axis en el wsdd.

viernes, 25 de septiembre de 2009

Las nuevas tecnologías

La comunicación de texto, imágenes y vídeo de forma fácil y rápida, permite que una empresa local de pequeño tamaño sea vista desde el otro lado del planeta, o que escuchemos a grupos musicales de cualquier lugar, algo impensable hace algunas décadas de forma tan sencilla. Pero además permite a cualquier ciudadano opinar, y escribir sus vivencias y ponerlas a disposición de todo el mundo. Esto es la verdadera revolución de internet. Las fronteras han caído en lo que respecta a cualquier ámbito de la vida, económico, social o político.

El concepto (ya casi obsoleto) de Web 2.0 centra sus directrices en una web más clara, más ligera y más interactiva, que son las claves para conseguir una innovación real a parte de las buenas ideas que despierten la curiosidad del navegante, y por ello debería seguir vigente y tenido en cuenta. Una buena idea sin el respaldo de una buena navegabilidad, y velocidad de respuesta, no tiene cabida hoy en día. El triunfo de Google, aunque no pasa por respetar demasiados estandares, si corrobora que sus diseños simples, son de gran utilidad, y así facebook etc, etc. Este mismo blog, tampoco lo hará (imagino), pero es algo que siempre pretendo tener en cuenta en mis proyectos.

Y en base a estas directrices es en las que hay que seguir trabajando. Los estándares del W3C son claves para el éxito de una web, pese a que "los grandes" no los respeten, o no los tengan en cuenta en sus barómetros, todos deberíamos ser más exigentes respecto a ello. Llevar a cabo un proyecto cuidando estos factores es una clave en la recurrencia de las visitas

Hoy en día no es dificil encontrar webs con una saturación de contenidos en cada página que se visita, y carecen de un menú completo y descriptivo. En ese sentido deberíamos educar a los clientes, a las personas a las que realizamos la consultoría. ¿o no?

martes, 28 de julio de 2009

Estudio de grabación - Compilando Ardour 2.8.2 VST y Jack 0.116.2 en ubuntu

Pues como ya he comentado en otro post, mi interés en la grabación digital de audio viene desde tiempo atrás, cuando mi hermano se hizo con una pequeña mesa de mezclas Mackie y una tarjeta de sonido Terratec EWS88/MT, allá por el año... ni me acuerdo. Ese fué el primer equípo que utilizamos en nuestras grabaciónes caseras, junto con el programa de grabación de audio Logic.

Aunque la mesa solo tiene 4 entradas I/O balanceadas, los previos que tienen las mesas Mackie tienen una relación calidad/precio de las más elevadas. Actualmente, habiendo renovado también el equípo informático, nos hemos hecho con un módulo de previos a válvulas que incorporan ecualización y compresión de la señal. Además, para completar 8 pistas, de una pequeña mesa Yamaha utilizamos dos de sus inserts.

Todo esto lo hemos ido completando con sets de micros cada vez mejores donde no falta un set de microfoneado de batería AKG, micrófonos de condensador para ambiente, así como el conocido Shure SM57... uno de los micros mas versátiles del mercado, que graba la caja de mi batería con una pegada increible, y recoje a la perfección los agudos de una guitarra eléctrica.

Por otro lado, hace poco que terminamos una obra enorme en el local, que ha quedado como un auténtico estudio de grabación. Hemos tenído en cuenta desde las paredes, de madera y espuma acustica para evitar reflexiones en frecuencias medias, así como trampas de graves con "Rockwool" para el techo, tarima flotante con grosores mayores tanto para las piezas como para la espuma etc.

Y después de todo esto hay que sacarle partido. Hace tiempo que dejé de usar los sistemas Windows, por cuestiónes éticas, y en esto de la música no quería ser menos, así que me informé de las opciónes libres, y hasta el momento no puedo tener queja. Me he dado cuenta de que la grabación tiene más calidad, mas cuerpo y más realismo, aunque parezca imposible. He probado distribuciónes específicas como Musix y Ubuntu Studio, pero al final uso Ubuntu desktop 9.04 con el kernel rt, Ardour 2.8.2 sin Plugins VST pero con los LV2, que son una auténtica maravilla, así como Jack 0.116.2.
Lo peor es que en los repositorios de Ubuntu, así como de otras distros, las versiónes tanto de Ardour como de Jack no están actualizadas del todo, y en un proyecto tan vivo como Ardour, estas actualizaciónes incluyen mejoras significativas. Además no basta con instalar el kernel rt, sino que hay que asignar recursos adicionales del sistema para que realmente se pueda iniciar el servidor jack activando el modo rt y reducir la latencia de la señal, y un rendimiento mayor del equipo. Evidentemente todo dependerá de tu hardware, pero en mi caso, mi Terratec EWS88/MT tiene una latencia con la configuración por defecto, de 46 ms y configurando jack adecuadamente (sin xruns) baja a 5,4 ms, lo cual no está mal considerando los 128 ms de latencia que obtenía con un kernel "generic".

Antes de nada, comentar que me pareció sencillamente increible que Ubuntu detectase automáticamente mi Terratec con los drivers ALSA para tarjetas Envy24 (ICE), y empezase a funcionar perfectamente sin instalar nada, más allá del panel de control de la tarjeta, el "Envy24 Control", que también funciona a la perfección (en Windows XP tuve que buscar los drivers y descargarlos de una página de dudosa intención).

Y así, manos a la obra. Vamos a instalar y configurar el kernel realtime de ubuntu. La instalación de un nuevo kernel hoy en día no implica (necesariamente) nada complicado como una compilación o cosas así, que en el pasado nos han hecho renunciar. Ahora solo hay que abrir el gestor de paquetes de ubuntu (Synaptic) y buscar "linux rt" e instalar:
  • linux-image-rt
  • linux-headers-rt
  • linux-restricted-modules-rt
Una vez hecho esto, nos encontraremos con una opción más de inicio en el GRUB, que nos permitirá arrancar con dicho kernel, o para hacer que Ubuntu arranque con ese kernel, editar el archivo /boot/grub/menu.lst y hacer que por defecto arranque con ese kernel, indicando el número de opción del menu de grub en la sentencia default.

Ahora nos toca configurar el sistema para que jack tenga todos los recursos necesarios y aprovechar el rendimiento de este kernel lo máximo posible. Básicamente se debe configurar la cantidad de memoria que un proceso puede bloquear para si, ejecutandose como el usuario con el que entremos en ubuntu. Esta configuración básica la encontramos en el archivo /etc/security/limits.conf. La sintaxis de las líneas en este archivo es:

{nombre_de_usuario} {tipo_de_limite} {item} {valor}


de forma que podemos añadir unas líneas como las que vemos a continuación:
@audio - rtprio 99
@audio - nice -10
@audio - memlock unlimited
Donde @audio es el nombre del grupo de usuarios para el que asignamos los límites. Para el parámetro memlock también podemos calcular un tamaño en Kb en función de la RAM que tengamos y de lo que nos permita el sistema. Desde los desarrolladores de Jack recomiendan unlimited. El parámetro nice puedes también asignarle -15 en determinados equipos con lo que los procesos tendrán más prioridad. Por supuesto deberás crear el grupo audio y asignar tu usuario a dicho grupo, o cambiar el nombre del grupo por alguno al que ya pertenezcas.

Para la instalación de Jack además, es necesaria una partición para el directorio de archivos temporales que utiliza Jack y para ello creamos un directorio:

sudo mkdir /mnt/ramfs

Y añadimos la siguiente línea en /etc/fstab:

none /mnt/ramfs tmpfs defaults 0 0

Cuando reiniciemos el equipo, podremos comprobar en "Sistema > Administración > Monitor del sistema" que tenemos ubuntu arrancado con el nuevo kernel y la nueva asignación de prioridades etc.

Ya tenemos nuestro equipo listo para instalar Jack y Ardour. Jack es el servidor de audio, y permite establecer la ruta de las señales de audio que tengamos en nuestro equipo entrando y saliendo, derivandolas a plugins de efectos, a otras aplicaciónes como Jamin, o incluso con JackNet a otros equipos que podríamos utilizar como procesadores de efectos.
Ardour es una aplicación que nos dá una interfaz para realizar proyectos de audio utilizando Jack, y nos permite grabar, ecualizar, filtrar, y manipular las señales de audio. Así que nos descargamos:
Y ahora es cuando deberemos instalar unas cuantas librerías que nos permitan realizar una compilación correcta de ambos sistemas. Aquí os dejo las ordenes, que solo tendréis que copiar y pegar en un terminal y con permisos de root. Algunos paquetes están duplicados pero weno no os preocupéis puesto que los gestores de paquetes son mágníficos...

sudo apt-get install libxine1 libxine-dev libxine1-gnome libxine1-misc-plugins gxine gstreamer0.10-plugins-ugly-multiverse gstreamer0.10-plugins-ugly gstreamer0.10-plugins-bad-multiverse gstreamer0.10-plugins-bad gstreamer0.10-pitfdll gstreamer0.10-ffmpeg jamin audacity jack libmp3lame0 jack-tools libjackasyn0 liblo0-dev libqt4-dev python-ogg-dbg jack-tools meterbridge libjackasyn0 nas libfftw3-dev liblo0-dev libqt4-dev python-ogg-dbg python-pyvorbis-dbg csladspa libfftw3-dev liblo0-dev libqt4-dev python-ogg-dbg python-pyvorbis-dbg qt4-dev-tools libmysqlclient15-dev libsqlite3-dev libiodbc2-dev audiooss phonon-backend-xine alsa-tools-gui build-essential libxml2 scons gettext pkg-config libtool xml2 libxslt1.1 python-libxslt1 libmodxslt0 libxalan110 xalan xmlstarlet libart-2.0-2 libart-2.0-dev libart2.24-cil libart-dev libart2 libgdk-pixbuf2 libgdk-pixbuf-dev libart2-ruby libasound2-plugins libsamplerate0 libsamplerate0-dev libgavl1 libgavl-dev raptor-utils libraptor1 libraptor1-dev liblrdf0 liblrdf0-dev jack-rack blepvco blop caps dssi-dev dssi-example-plugins dssi-utils fil-plugins jackeq libladspa-ocaml libladspa-ocaml-dev lv2core mcp-plugins rev-plugins rubberband-ladspa ladspa-sdk muse ubuntustudio-audio-plugins libgnome2-canvas-perl libgnomecanvas2-0 libgnomecanvas2-common libgnomecanvas2-dev libgnomecanvasmm-2.6-1c2a libgnomecanvasmm-2.6-dev guile-gnome0-canvas libgnomecanvas2-ruby1.8 libfftw3-3 libfftw3-dev pd-aubio python-aubio libaubio-dev libaubio2 aubio-tools libsndfile1 libsndfile1-dev wine wine-dev libsvn1 libsvn-perl subversion subversion-tools boost-build libboost-signals-dev libboost-regex-dev libboost-graph-dev libboost-dev libusb-1.0-0 libusb-1.0-0-dev libusbprog-dev alsa-firmware-loaders libdiscover-dev libdiscover2 libusb++-dev libmtp-dev libmtp8 libgphoto2-2 libgphoto2-2-dev alsa-source alsa-tools libbio2jack0 libbio2jack0-dev libbjack-ocaml libbjack-ocaml-dev libclalsadrv-dev libclalsadrv1 liblash-dev liblash2 liblo10k1-0 liblo10k1-dev libopenal-dev libopenal1 bse-alsa libesd-alsa0 libasound2-plugins libasound2-dev libasound2 libao2 gstreamer0.10-alsa alsa-base libpt2.6.1-plugins-alsa automake autoconf autotools-dev gnome-common libsigc++-2.0-0c2a libsigc++-2.0-dev libsigc++-1.2-5c2 libsigc++-1.2-dev libsigc++-dev lv2core libecasound2.2-dev libtse3-dev libwildmidi-dev libwildmidi0 libsdl-mixer1.2 libsdl-mixer1.2-dev dssi-host-jack libfluidsynth-dev libfluidsynth1 libportmidi-dev libportmidi0 redland-utils libsoprano4 librdf-perl librdf-ruby python-librdf librdf0 librdf0-dev libdmalloc-dev libxklavier12 libxklavier12-dev libdmalloc5

Un tostón, además os recomiendo no hacerlo de un tirón, pero enhorabuena!!! Ahora eres capaz de compilar un sistema de audio profesional completo!!! Además, ahora también podrás compilar el core de LV2, las librerías SLV2 y los plugins ll etc. es lo bueno de esta orden...

Evidentemente si has ejecutado todo lo anterior, ya tienes instalado Jack, en la versión del repositorio de Ubuntu, pero si quieres la última versión, escribe desde un terminal en el directorio donde has descomprimido los fuentes de jack:

./configure --with-default-tmpdir=/mnt/ramfs
make
sudo make install


Esto te compilará e instalará el ejecutable de Jack en /usr/local/bin/jackd, recuerda esto cuando intentes iniciar el demonio, y cuando configures qjackcontrol. Con estos nuevos parámetros, y dependiendo de la tarjeta de sonido que tengas, podrás ajustar el parametro de "Cuadros/periodo" (frames/period) para reducir la latencia. Yo actualmente tengo 5 ms con 256 frames/period, y ningún xrun.

Para compilar ardour vete preparando una taza de café, unos puritos e incluso un tablero de parchis porque va a tardar un poquito... jeje... Así que cuanto antes mejor. Entra en el directorio donde descomprimiste Ardour, y escribe:

scons LV2=1 FFT_ANALYSIS=1 SLV2=1 VST=1
sudo scons install


Imagino que no es muy normal que haya que intentarlo varias veces, pero en ocasiones, me fallo la compilación y misteriosamente al volver a intentarlo no da error. Supongo que el orden en script de scons estará mal, o hay interdependencias raras... vete tu a saber... La opción de VST es posible si has instalado todas las librerías que he mencionado, pero lo cierto es que aunque es más estable que antes, no va del todo bien, y los plugins LV2 y Jamin permiten hacer maravillas. Bueno pues si has sido capaz de realizar estos pasos tan sencillos, ya tienes un sistema de audio bastante profesional, y gratuito, a disfrutarlo.

lunes, 27 de julio de 2009

Montar GWT-Ext en Netbeans

Requisitos

Todo esto ha sido probado con el siguiente software y con las versiónes mencionadas a continuación, los cuales habrá que descargar:

  1. Netbeans (version 6.7)
  2. GWT (version linux-1.6.4)
  3. Gwt-Ext (versión 2.0.6)
  4. Ext (v2.0.2 - es la version que soporta GWT-Ext 2.0.6)

Proceso

  1. Instalar el Plugin que soporta GWT desde Netbeans
  2. Instalar la librería Gwt-Ext en Netbeans.
  3. Iniciar un proyecto GWT
  4. Agregar librería Javascript ExtJS al proyecto
    1. Modificación del archivo: welcomeGWT.html
    2. Modificación del archivo: Main.gwt.xml
  5. Compilar y corregir errores de compilación en GWT4NB
    1. Desde Netbeans
    2. Desde nuestro Proyecto
  6. Prueba

Proceso detallado de creación de un proyecto GWT-Ext

Instalar el Plugin que soporta GWT desde Netbeans

  1. Vamos a Netbeans y en el menu de arriba buscamos: Tools > Plugins > pestaña Available Plugins, y en el casillero de busqueda escribimos para filtrar: GWT y seleccionamos el plugin GWT4NB
  2. Si no lo encontramos, podemos descargar el .nbm desde aqui y después desde Tools > Plugins > pestaña de Downloaded buscamos el archivo
  3. Después descomprimimos GWT en la carpeta que queramos, por ejemplo en /home/juan/gwt-xxx-1.5.x….

Instalar la librería Gwt-Ext en Netbeans

Descomprimimos Gwt-Ext y creamos una carpeta dentro de la carpeta de GWT con el nombre lib y copiamos gwtext.jar ahí (/home/juan/gwt-xx../lib/gwtext.jar) y después la agreguamos al proyecto así:
  1. Hacemos click Tools > Libraries. Se abrira una ventana y
  2. Elegimos New Library, ponemos un nombre representativo como gwtext y Library Type lo dejams como esta (Class Libraries). Le damos al ok.
  3. Le damos a Add JAR/Folder y buscamos el archivo gwtext.jar dentro de la carpeta que descomprimimos (/home/juan/gwt-xx/lib/gwt-ext/gwtext.jar)

Le damos al ok hasta terminar y listo

Iniciar un Proyecto GWT

Vamos a crear un nuevo proyecto en Netbeans con GWT-EXT una vez hecho todo lo anterior.

  1. Elegimos:Web > Web Application Le ponemos un nombre y le damos Siguiente/Next,
  2. Elegimos el servidor, la versión de jvm y el context path, y damos a Siguiente/Next.
  3. En Framework elegimos Google Web Toolkit y abajo:
    1. En GWT Installation Folder ponemos la ruta donde descomprimimos gwt (/home/juan/gwt-xx…)
    2. En GWT Module ponemos el nombre de la clase donde implementaremos el punto de entrada a la aplicación. Es decir, la página de bienvenida para la aplicación, por lo que deberíamos poner el nombre de paquete que vayamos a utilizar, y un nombre de clase como Main, Index, o Welcome.. a vuestro gusto. yo por ejemplo prueba.gwt.Main.
  4. Una vez creado, desplegamos el proy ecto, y hacemos click derecho sobre Libraries > Add Library, y añadimos la librería creada anteriormente como gwtext.

Listo para jugar con GWT.

Agregar la librería Javascript ExtJS

Descomprimimos Ext. Vamos a copiar los archivos necesarios en una carpeta dentro de la carpeta web de nuestro proyecto creada como js/ext… algo parecido a: /home/juan/NetBeansProjects/ProyectoGWT/web/js/ext, y los archivos que tenemos que copiar de la carpeta de origen a esta son:
  • ext-all.js
  • ext-all-debug.js
  • ext-core.js
  • ext-core-debug.js
  • /resources (carpeta completa)
  • /adapter (carpeta completa)
  • /build/locale/ext-lang-es.js

Una vez hecho esto tenemos que hacer unas modificaciones al proyecto para que use estos scripts.

Modificación del archivo: welcomeGWT.html

En Netbeans dentro de nuestro proyecto vamos a Web pages y abrimos el archivo:welcomeGWT.html. Ese archivo tendrá que incluir en las cabeceras los scripts de ExtJS que acabamos de agregar al proyecto, así tendremos que agregar dentro de la entiqueta <head> las siguientes líneas.

<link rel="stylesheet" type="text/css" href="js/ext/resources/css/ext-all.css">
<script type="text/javascript" src="js/ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="js/ext/ext-all.js"></script>
<script type="text/javascript" src="js/ext/ext-lang-es.js"></script>

Modificación del archivo: Main.gwt.xml

Vamos ahora a los Source Packages y buscamos en el paquete que especificamos como Gwt Module (prueba.gwt en mi caso) el archivo de configuración de gwt que el plugin ha creado Main.gwt.xml (en mi caso) y abrimos el archivo para editarlo, agregando esta linea en la etiqueta module:

Quedaría algo así:

<inherits name="com.google.gwt.user.User">
<inherits name="com.gwtext.GwtExt">
<entry-point class="org.yournamehere.client.MainEntryPoint">
<!-- Do not define servlets here, use web.xml -->
</module>

Compilando y corrigiendo error en el plugin GWT4NB

Cuando compilemos probablemente (al menos con las versiónes de Netbeans 6.7, Ext-2.0.2, Gwt-Ext 2.0.6 y gwt-linux-1.6.4) dará un error en el archivo /home/juan/NetbeansProjects/ProyectoGwt/nbproject/build-gwt.xml (en mi caso recordad) del tipo java returned: -1 y de deprecación de la clase com.google.gwt.dev.GWTCompiler. Podemos modificar este archivo. Una vez que nos da el error, Netbeans va a resaltar donde esta así es que le hacemos click para que nos lleve hasta alli, donde vamos a ver este codigo:

<java classpath="${javac.classpath}:${src.dir}" failonerror="true"
classname="com.google.gwt.dev.GWTCompiler" fork="true" jvmargs="${gwt.compiler.jvmargs}">
<arg value="-out">
<arg path="${build.web.dir}/">
<arg value="-style">
<arg value="${gwt.compiler.output.style}">
<
<arg value="${gwt.compiler.logLevel}">
<arg value="${gwt.module}">
</java>

Tiene que quedar igual que este:

<java classpath="${javac.classpath}:${src.dir}" failonerror="true"
classname="com.google.gwt.dev.Compiler" fork="true" jvmargs="${gwt.compiler.jvmargs}">
<arg value="-war">
<arg path="${build.web.dir}/">
<arg value="-style">
<arg value="${gwt.compiler.output.style}">
<arg value="-logLevel">
<arg value="${gwt.compiler.logLevel}">
<arg value="${gwt.module}">

<jvmarg value="-Xmx512m">
</java>

Que sustituye al parámetro en el tag El principal inconveniente es que algunas veces (con Netbeans 6.1) tras hacer un Clean & Build, el archivo volvía a su estado original y volvía a fallar. Otra forma de solucionar esto esta en el archivo de nuestro proyecto:/home/juan/NetbeansProjects/ProyectoGwt/nbproject/gwt.properties, donde se definen todos los parámetros y donde podremos asignar:

gwt.compiler.class=com.google.gwt.dev.Compiler
gwt.compiler.jvmargs=-Xmx512m

Y hacer la referencia a ella en build-gwt.xml mediante el siguiente código en build-gwt.xml.

<java classpath="${javac.classpath}:${src.dir}" failonerror="true"
classname="${
gwt.compiler.class}" fork="true" jvmargs="${gwt.compiler.jvmargs}">
<arg value="-war">
<arg path="${build.web.dir}/">
<arg value="-style">
<arg value="${gwt.compiler.output.style}">
<arg value="-logLevel">
<arg value="${gwt.compiler.logLevel}">
<arg value="${gwt.module}">

<jvmarg value="-Xmx512m">
</java>

Eso nos permite que en la próxima compilación, asigne más memoria al proceso de compilación y no falle...Y con esto y un bizcocho pues comele a la burra el… Espero que os funcione…