Cliente .Net para WebServices Java/Axis2/WS-Security sobre HTTPS

dotnet_2010

Se me solicito realizar un implementación de WebServices para publicar los servicios de la Empresa para la cual estoy dando servicios.

Una vez terminado dicho proyecto, se procedió a realizar las pruebas necesarias de la implementación, para esto ser utilizo la herramienta SoapUI, sin encontrar inconvenientes en el consumo de estos (https + ws-security).

Bueno, todo estaba bien, hasta que se intento realizar un demo con .Net (VS2010).

Dejo una URL donde aparece una forma bastante “didáctica” de como consumir un WebService:
http://www.elguille.info/colabora/NET2005/sergio_CallWebService.htm

Una vez realizado dicha tarea, nos agrega la siguiente configuración al archivo app.config:
25-04-2012 03-29-57 p-m-

Seleccionamos el EndPoint que vamos a utilizar, en nuestro ejemplo:
25-04-2012 03-33-42 p-m-

El código utilizado para la llamada al WebService es el siguiente:
25-04-2012 03-38-51 p-m-

Cuando ejecutamos el programa ejemplo, nos encontramos con el primer problema grave, que es el reclamo que el certificado es “falso”:
25-04-2012 04-34-52 p-m-

El sistema de seguridad del framework .Net es bastante exigente en ese punto. Para poder continuar con nuestras pruebas, vamos a “enganchar” una función que realice esta funcionalidad y no el framework:

ServicePointManager.ServerCertificateValidationCallback =
                new RemoteCertificateValidationCallback(IgnoreCertificateErrorHandler);

Donde la función es la siguiente:

public static bool IgnoreCertificateErrorHandler(
            object sender,
            X509Certificate certificate,
            X509Chain chain,
            SslPolicyErrors sslPolicyErrors)
        {
            System.Console.WriteLine("Warning, trust any certificate");

            return true;
        }
Solo retornamos “true” para todas las validaciones y con esto podemos continuar con la invocación del WebService:
25-04-2012 05-15-16 p-m-
 

Ahora si ejecutamos el programa, nos genera una excepción porque no cumplimos con los criterios de seguridad puestas en el WebService (WS-Security):

25-04-2012 05-16-41 p-m-

Para esto abrimos el archivo “app.config” de nuestro proyecto y le indicamos el nivel de seguridad necesario:

25-04-2012 05-22-00 p-m-

Lo cambiamos por:

25-04-2012 05-22-51 p-m-

Una vez hecho esto, ejecutamos nuestro programa obteniendo la siguiente respuesta:

25-04-2012 05-24-50 p-m-

Esto significa que el WebService nos esta exigiendo las credenciales necesarias impuesta en la configuración del WS-Security, para nuestro caso UserToken:

serviceProxy.ClientCredentials.UserName.UserName = "comercio1";
serviceProxy.ClientCredentials.UserName.Password = "comercio1";

Quedando nuestro programa de la siguiente forma:25-04-2012 05-55-07 p-m-

Ahora con esto, nuestra aplicación no debiese tener ningún inconveniente para poder consumir el WebService. Ejecutamos:

25-04-2012 06-03-55 p-m-

Otro error más!!! Si analizamos el mensaje:

El procesador de seguridad no encontró un encabezado de seguridad en el mensaje. La causa puede ser que el mensaje sea un error no protegido o que no coincidan los enlaces entre las partes de la comunicación. Esto puede suceder si el servicio esta configurado para seguridad y el cliente no usa seguridad.

Bueno!, ahora nos encontramos con este problema, lo cual analizando nuestro WebService, este si respondió al requerimiento, es decir, por el lado del servidor, todo esta funcionando correctamente; el mensaje fue recibido, fue procesado, y se obtuvo una respuesta exitosa al requerimiento. Pero algo no le gusto al “Procesador de Seguridad” de .Net que nos “atrapa” la respuesta.
 
Después de mucho buscar y analizar el problema, se encontró con una solución bastante atípica. La cual consiste en eliminar del mensaje la cabecera SOAP del requerimiento la fecha y hora (TimeStamp), para que de esta forma en la respuesta no viaja la cabecera SOAP, y evita que el “Procesador de Seguridad” haga la fallida comparación.
 
BindingElementCollection elements = serviceProxy.Endpoint.Binding.CreateBindingElements();
                elements.Find<SecurityBindingElement>().IncludeTimestamp = false;
                serviceProxy.Endpoint.Binding = new CustomBinding(elements);
Quedando nuestro código de la siguiente forma:

25-04-2012 06-32-21 p-m-
 
Ahora ejecutamos nuestro programa:

25-04-2012 06-49-39 p-m-
 
Y Funciona!. Espero que sea de ayuda….
 
Caluroso Marco!

 

Etiquetas de Technorati: ,,,,,,

Erlang/OTP Tolerancia a Fallos

erlang

Continuando con las características de este lenguaje, nos encontramos con la “Tolerancia a Fallos”.

Erlang tiene un manejo de excepciones además de un sistema de fallos de procesos muy eficiente, conocido como “Process Link” o “Enlace de Procesos”.

Cuando un proceso falla, este genera una señal/signal de salida. La cual llegan a todos los procesos que están relacionados, de esta forma los procesos que reciben la señal la envían a sus procesos relacionados y así sucesivamente; hasta que todos los procesos vinculados directamente o indirectamente han salido. Este comportamiento en escala nos permite no tener que preocuparnos por encontrar y matar/kill todos los procesos relacionados.

La filosofía de Erlang es “let it crash” (dejar que se estrelle). Esto para tratar de evitar el salvar una situación que probablemente no sea capaz de arreglar. De esta forma deja todo limpio para empezar de nuevo.

Los procesos tienen la capacidad de capturar un mensaje de salida y comprobarlos para tomar medidas. Para esto en Erlang existen los “Processes Supervisor” o “Supervisores”.

Los supervisores nos permiten agrupar un subsistema y reiniciarlo. La OTP trae consigo varias librerías que nos permitirán optimizar dicho proceso de reinicio sin necesidad de reiniciar el sistema completo. Los supervisores están siempre atentos a lo que sucede con los procesos. Estos supervisores están jerarquizados, es decir, existen supervisores para todo el sistema, supervisores para los subsistemas y supervisores para los procesos. De esta forma si un proceso falla, el supervisor informa a su supervisor mayor y así sucesivamente, hasta lograr restablecer el sistema.

Listo, esto por el momento!

Marco

Etiquetas de Technorati: erlang,otp,concurrencia,lenguaje,programación,tolerancia a fallos,fallos,funcional,procesos

[tweetmeme only_single=”false”]

Erlang/OTP Procesos

Etiquetas de Technorati: ,,

erlang

Para poder desarrollar un sistema en Erlang, lo primero es entender como funciona su run-time, y uno de los primeros puntos, son los procesos, ver como se gestiona la base de toda aplicación Erlang.

Los procesos en Erlang estas completamente protegidos manteniendo el entorno seguro. Sobre todo pensando que será el mismo proceso ejecutado concurrentemente. En caso de catástrofe solo el proceso en si, se ve afectado, permitiendo a los otros seguir funcionando.

Para iniciar el desarrollo de un programa Erlang lo primero es plantearse que actividades se pueden identificar como un proceso separado.

Los procesos Erlang no son los típicos Threads/Hilos generados desde el S.O.(Sistema Operativo). A diferencia de estos, son mucho más ligeros, ya que son implementados por el run-time de Erlang. Siendo cada proceso independiente del otro, ya que no se comparte memoria con los otros procesos en ejecución.

Los Threads/Hilos de S.O. reservan algunos Megabytes de espacio para direcciones en su PILA (Heap), produciendo el bloqueo en caso de que se llegue al limite. Los procesos Erlang comienzan solo con un par de bytes y crecen o se achican según sean necesario.

Para crear un proceso en Erlang se utiliza la función:

spawn

Para la siguiente función:

io:format("Hola Mundo!")

Si la invocamos como un proceso:

spawn(io, format, ["Hola Mundo!"])

De esta forma se genera  un proceso que ejecutara io:format(“Hola Mundo!”) de forma independiente del proceso que lo invoca. La función spawn tiene algunas variantes, pero la forma presentada es la más simple.

Les adjunto un Link donde podrán ver un resumen de lo que es Erlang y su sintaxis de programación: http://www.slideshare.net/SinarShebl/introduction-to-erlang-final

Continuando con los procesos; la forma de comunicarse de estos, es mediante mensajes. Cada proceso tiene un Mailbox, donde se almacenan los mensajes entrantes a medida que llegan, independiente si el proceso se encuentra actualmente ocupado.

Al ser los procesos independientes, no se pueden corromper unos a otros porque no comparten información/memoria/etc. Esta es una de las características especiales de Erlang La Tolerancia a Fallo (Fault Tolerance).

Espero se haya entendido,

Saludos, Marco!

[tweetmeme only_single=”false”]

Erlang (Software para un Mundo Concurrente!) xD

Me he decidido a implementar un pequeño Middleware Transaccional en este nuevo lenguaje Funcional llamado Erlang (wiki_es: Erlang es un lenguaje de programación concurrente y un sistema de ejecución que incluye una máquina virtual y bibliotecas).

La pregunta es ¿Porque dicho lenguaje?, acá van algunas de sus características que me llamaron bastante la atención:

  1. Es un lenguaje de programación funcional. Que significa? Que cambiar cualquier variable esta estrictamente prohibido. Si una variable es igual a 9, entonces no se puede admitir que su valor sea 10. También corre para las funciones a las cuales se les referencia o asigna los mismos parámetros, es decir, siempre devolverá el mismo valor. Para esto se le conoce como “Transparencia Referencial”.
  2. Tiene gran énfasis en la concurrencia: Es posible escribir programas que se ejecuten más rápido cuando se ejecutan en un entorno multi-nucleo.
  3. Se puede escribir aplicaciones de alta disponibilidad, permitiendo la modificación de estos “en caliente” sin necesidad de bajar el servicio.
  4. Y esta es la más interesante… el nivel de líneas de código es bastante reducida, ya que la cantidad de librerías, la concurrencia y alta disponibilidad de la plataforma, nos permite solo concéntranos en la funcionalidad real de la aplicación, bajando bastante las líneas de código a escribir.
  5. Iniciar en un nuevo patrón de Programación llamado Programación Orientada a la Concurrencia. La idea final, no es realizar un tutorial o manual de instalación y programación de Erlang, si que compartir el desarrollo de distintos sistemas que vayan siendo realizados con este lenguaje.

Links Básicos:
Erlang en Wikipedia (es) (es.wikipedia.org/wiki/Erlang)
Web Oficial (www.erlang.org)
http://erlangexamples.com/
http://ceciliaurbina.blogspot.com/2010/10/erlang.html
http://aprendiendo-erlang.blogspot.com/

Para la próxima entrega, iniciaremos un primer proyecto de construcción del mini middleware.

Saludos, Marco.

[tweetmeme only_single=”false”]

Agregando propiedades a nuestro JPos-Q2Server

jpos.org

jpos.org

Hay situaciones donde tenemos que agregarle información desde el archivo de configuración del JPos Q2Server. Utilizando nuestro proyecto anterior, le vamos agregar a la configuración, información de acceso a una base de datos donde vamos a almacenar la data que se procesa. Solo voy a incluir el código para acceder a dicha información, en algún pos futuro veremos como insertar efectivamente la transacción.

Tenemos nuestro actual archivo de configuración para el Q2Server:

Archivo configuración QServer

Archivo configuración QServer

Le agregamos las siguientes lineas, a nuestro archivo de configuración (lo que esta en rojo, ya esta en el archivo, solo se indican para ubicar correctamente la información):

<request-listener class="cl.gomark.listener.RequestListener" logger="Q2">
<property name="db.driver" value="org.postgresql.Driver" />
<property name="db.url" value="jdbc:postgresql://localhost/gomark_24082010" />
<property name="db.user" value="postgres" />
<property name="db.password" value="****" />
</request-listener>

Con esto nos queda el siguiente archivo de configuración (en mi caso de nombre 90-gomark-server.xml):

Configuración Q2Server

Configuración Q2Server

Una vez con nuestro archivo de configuración ya listo, modificamos nuestra clase (le agregamos la implementación ReConfigurable):

public class RequestListener extends Log implements ISORequestListener,
ReConfigurable, LogSource {

Luego agregamos el siguiente metodo a nuestra clase “RequestListener”:

@Override

public void setConfiguration(Configuration configuration) {

	_config = configuration;

	LogEvent logEvt = new LogEvent(this, "RequestListener:setConfiguration");

	logEvt.addMessage("db.driver = " + _config.get("db.driver"));

	logEvt.addMessage("db.url = " + _config.get("db.url"));

	logEvt.addMessage("db.user = " + _config.get("db.user"));

	logEvt.addMessage("db.password = " + _config.get("db.password"));		

	Logger.log(logEvt);

}

Donde _config es una propieda de la clase de tipo privada, la cual contiene toda la configuración agregada al archivo, para extraer un respectivo dato:

String miValor = _config.get(“db.url”);

Si todo sale bien, cuando iniciemos nuestro servicio JPos Q2Server, deviese verse de la siguiente forma:

Bueno, esto seria por esta vez. Cualquier comentario, es bienvenido!

Saludos!

Intalación JPOS en Ubuntu 10.4

Para poder instalar JPOS, se requieren tener instalada las siguientes herramientas:

  1. Java JDK (mini Howto para instalar jdk en ubuntu 10.4 http://www.ubuntu-es.org/node/133779)
  2. Subversion (instalar subversion: sudo aptitude install subversion)
  3. ANT (instalar ant: sudo apt-get install ant ant-optional)

Una vez instalada las herramientas, iniciamos la descarga desde el repositorio de la rama en desarrollo de JPOS (existe una versión estable para descarga en http://www.jpos.org)

svn co https://jpos.svn.sourceforge.net/svnroot/jpos/trunk/jpos6/ jpos-1.6.9

donde jpos-1.6.9 es el nombre del directorio donde lo vamos a alojar (el nombre puede ser cualquiera)

Una vez finalizado el proceso de descarga, procedemos a compilar vía ant (todo esto dentro del directorio donde alojamos el proyecto jpos)

moo@rcx01:~/jpos-1.6.9$ ant
Buildfile: build.xml
prepare:
[echo] Build jPOS-1.6.9.2010.08.19.03.52.17
[mkdir] Created dir: /home/moo/jpos-1.6.9/build
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/src
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/lib
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/lib/test
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/bin
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/doc
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/cfg
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/modules
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/deploy
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/deploy/lib
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/webapps/root
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/classes
[mkdir] Created dir: /home/moo/jpos-1.6.9/dist
[mkdir] Created dir: /home/moo/jpos-1.6.9/build/log
copy-lib:
[copy] Copying 7 files to /home/moo/jpos-1.6.9/build/lib
modules:
[copy] Copying 620 files to /home/moo/jpos-1.6.9/build/modules
[copy] Copying 2 files to /home/moo/jpos-1.6.9/build/deploy
[copy] Copying 2 files to /home/moo/jpos-1.6.9/build/lib
[copy] Copying 592 files to /home/moo/jpos-1.6.9/build
prepare:
[echo] Build jPOS-1.6.9.2010.08.19.03.52.17
support:
[copy] Copying 12 files to /home/moo/jpos-1.6.9/build/classes
[subant] No sub-builds to iterate on
[subant] No sub-builds to iterate on
copy-bin:
[copy] Copying 3 files to /home/moo/jpos-1.6.9/build/bin
manifest:
main:
[javac] Compiling 465 source files to /home/moo/jpos-1.6.9/build/classes
[javac] Note: Some input files use or override a deprecated API.
[javac] Note: Recompile with -Xlint:deprecation for details.
[javac] Note: Some input files use unchecked or unsafe operations.
[javac] Note: Recompile with -Xlint:unchecked for details.
[rmic] RMI Compiling 2 classes to /home/moo/jpos-1.6.9/build/classes
support:
[copy] Copying 12 files to /home/moo/jpos-1.6.9/build/classes
jar:
[jar] Building jar: /home/moo/jpos-1.6.9/build/jpos.jar
compile:
BUILD SUCCESSFUL
Total time: 12 seconds
moo@rcx01:~/jpos-1.6.9$
Para ejecutar nuestro Jpos, procedemos:
moo@rcx01:~/jpos-1.6.9$ ant run
Buildfile: build.xml
prepare:
[echo] Build jPOS-1.6.9.2010.08.19.03.56.47
copy-lib:
modules:
[copy] Copying 2 files to /home/moo/jpos-1.6.9/build/modules
prepare:
[echo] Build jPOS-1.6.9.2010.08.19.03.56.47
support:
[copy] Copying 12 files to /home/moo/jpos-1.6.9/build/classes
[subant] No sub-builds to iterate on
[subant] No sub-builds to iterate on
support:
[copy] Copying 12 files to /home/moo/jpos-1.6.9/build/classes
copy-bin:
manifest:
main:
jar:
[jar] Building jar: /home/moo/jpos-1.6.9/build/jpos.jar
run:
[java] <log realm=”Q2.system” at=”Thu Aug 19 15:56:51 CLT 2010.282″>
[java]   <info>
[java]     Q2 started, deployDir=/home/moo/jpos-1.6.9/build/deploy
[java]   </info>
[java] </log>
[java] <log realm=”Q2.system” at=”Thu Aug 19 15:56:51 CLT 2010.340″>
[java]   <info>
[java]     new classloader [22c95b] has been created
[java]   </info>
[java] </log>
[java] <log realm=”Q2.system” at=”Thu Aug 19 15:56:51 CLT 2010.342″>
[java]   <info>
[java]     deploy:/home/moo/jpos-1.6.9/build/deploy/99_sysmon.xml
[java]   </info>
[java] </log>
[java] <log realm=”org.jpos.q2.qbean.SystemMonitor” at=”Thu Aug 19 15:56:51 CLT 2010.357″>
[java]   <info>
[java]     Starting SystemMonitor
[java]   </info>
[java] </log>
[java] <log realm=”org.jpos.q2.qbean.SystemMonitor” at=”Thu Aug 19 15:56:51 CLT 2010.361″>
[java]   <info>
[java]     <release>jPOS 1.6.9 r2962</release>
[java]     <instance>c669c33b-d2c1-43c8-a1ef-83dc517c4018</instance>
[java]     <uptime>00:00:00.409</uptime>
[java]     <memory>
[java]        freeMemory=7206848
[java]       totalMemory=7995392
[java]       inUseMemory=788544
[java]     </memory>
[java]     <threads>
[java]             delay=0 ms
[java]           threads=4
[java]             Thread[Reference Handler,10,system]
[java]             Thread[Finalizer,8,system]
[java]             Thread[Signal Dispatcher,9,system]
[java]             Thread[Q2-c669c33b-d2c1-43c8-a1ef-83dc517c4018,5,main]
[java]             Thread[DestroyJavaVM,5,main]
[java]             Thread[Timer-0,5,main]
[java]             Thread[SystemMonitor,5,main]
[java]     </threads>
[java]     — name-registrar —
[java]       logger.Q2: org.jpos.util.Logger
[java]       logger.Q2.buffered: org.jpos.util.BufferedLogListener
[java]   </info>
[java] </log>
Ahí una forma muy básica de instalar jpos en un ubuntu (para windows es bastante similar)