Conexion Magento, Axis2 , java, Opencms

Conexion Magento, Axis2 , java, Opencms 

Un poco aparatoso el titulo cierto , pero de eso se trataba el trabajo que nos llego, una empresa que llamaremos EmpresaT, tiene una tienda virtual con subtiendas , y un gran catalogo de productos , se intereso en nuestro medio de pago (www.pinvalidda.com) hay perdonan la cuña publicitaria, pero sirve para contextualizar el problema, hasta ahora cuando alguien deseaba conectarse con nosotros , la forma era simple ,  le entregamos el botón de pago de nuestro sistema y empiece a vender que nosotros le recojemos el dinero por una peque ña comisión sobre la venta, y todo era felicidad y comiamos perdices en el gran reino virtual pinvalidda, pero no, tenia que llegar la serpiente del conocimiento a sembrar la tentacion y aquí estamos tratando de conectar a Magento desarrollado en PHP en nuestro querido y virginal sistema todo en Java.

En un principio pensé , no hay problema , debe haber una forma de hacerlo , que quede todo en java y me aplique a la tarea de buscar la forma de hacerlo.
Desde luego la información existía , pero mas bien confusa y reducida, en resumen, palabras mas , palabras menos se sintetizaba en lo siguiente:

1. Ingresar al administrador MAGENTO
2. Crear una cuenta de web service
3. Crear un perfil con todos los permisos
4. Asignar el perfil creada a la cuenta recién establecida
5. Buscar en configiracion la forma de  establecer el WSI complient que después de buscar que era el famoso WSI, me entere que es una empresa que esta tratando de establecer un protocolo unificado para las interfaces vía web service, con bastante exito dicen , bajo la revisión V2, pues según los entendidos
el modelo V1 , deja mucho que desear respecto a el uso de métodos , definición de variables, paso de parámetros etc.

Bueno el caso es que si quieres usar Java para comunicar Magento tienes que cumplir estas exigencias en el Magento.
Bueno bien juicioso y siguiendo el libro como dice un amigo quedóel Magento configurado.

Luego busque mi webservice para establcer los primeros pinitos y hacer que el WSDL2java me genera el stub para poder usarlo en mi programa para cargar los datos de Magento que necesitaba.

El siguiente script me creó el stub , tal cual decia que funcionaba, se debe notar 
la palabra v2_soap en la ruta, que le indica al wsdl2java que estas en protocolo V2 y en wsi complient, sino colocas el v2 , vas perder cantidad de tiempo y el java , no que no.

El script para crear el stub
----------------------------------------------------------------------------------------------------------------------
/usr/local/axis2/bin/wsdl2java.sh -d adb -uri \
http://empresax.com/api/v2_soap?wsdl=1 -o client
-----------------------------------------------------------------------------------------------------------------------

Luego haciendo caso de los instructivos de los que saben esta vaina , muy aplicado si señor ,cree un pequeño test , para cargar mi datos. así

Donde se pretende conectarse a magento, explorar en la tabla salesOrder
los pedidos no pagados por un usuario, para desplegarlos en pantalla y 
solicitarle al cliente cual quiere pagar.
Aqui el programa java que implemente

Con filtro en el correo del cliente y mostrando el valor a pagar
-------------------------------------------------------------------------------------------------------------------------

package magento ;

import java.util.Iterator;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;

import magento.*;
import magento.MagentoServiceStub.*;

public class Test
{
  public static void main(String[] args) throws Exception
  {

     MagentoServiceStub cliente = new MagentoServiceStub("http://empresaT.com/api/v2_soap");

     LoginParam loginParametros = new LoginParam()                        ;
     loginParametros.setUsername("miCuenta")                                     ;
     loginParametros.setApiKey("miClave")                                            ;
     LoginResponseParam loginRespuesta = cliente.login(loginParametros)            ;
     String             sessionId      = loginRespuesta.getResult()                ;
     System.out.println("Identificador de Seccion: " + sessionId)           ;

SalesOrderListRequestParam  sol = new SalesOrderListRequestParam()            ;
     Filters                  filtro = new Filters()                               ;

     AssociativeEntity      associaE = new AssociativeEntity()               ;
     associaE.setKey("customer_email")                                                 ;
     associaE.setValue("'micliente@gmail.com'")                                   ;

     AssociativeEntity[]       assA =  {associaE}                                    ;

     AssociativeArray      associaA = new AssociativeArray()               ;
     associaA.setComplexObjectArray(assA)                                         ;

     filtro.setFilter(associaA)                                                       ;
     sol.setSessionId(sessionId)                                                   ;
     sol.setFilters(filtro)                                                               ;
     SalesOrderListResponseParam solr = cliente.salesOrderList(sol)       ;
     SalesOrderListEntityArray   resSO= solr.getResult()                           ;

         List<SalesOrderEntity> ventas = org.apache.axis2.databinding.utils.ConverterUtil.toList(resSO.getComplexObjectArray());


     for (SalesOrderEntity v : ventas)
        {
      System.out.println("Id: " + v.getCustomer_email() + " Total " + v.getGrand_total() );
        }


     EndSessionParam finSeccion = new EndSessionParam()        ;
     finSeccion.setSessionId(sessionId)                                            ;
     EndSessionResponseParam finResultado = cliente.endSession(finSeccion)         ;
     System.out.println("Resultado fin seccion: " + finResultado.getResult())      ;
    

    }
}   

--------------------------------------------------------------------------------------------------------------------------

Una vez ejecutado el sistema me mostró que efectivamente encontró la ruta del webservice, que inicio sección y que cargo el catalogo de productos , pero no filtro nada , me mostró todos los clientes del catalogo, unos 250.000 mas o menos, con 140 campos cada registro, bueno pensé no hay problema , lo cargo y en mi buen java lo filtro y san se acabo el problema,  claro ingenuo , un buen STACK OVERFLOW, me volvió a la realidad , si  hay problema  y es serio, después de perder mas de 15 días , cambiando el filtro entendiendo y oscilando entre que no filtraba la informacion y me mostraba errores como,


Exception in thread "main" org.apache.axis2.AxisFault: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '= '')' at line 3
 Ensaye cambiando las comillas del filtro:

   associaE.setKey("customer_email")                                                 ;
   associaE.setValue("'micliente@gmail.com'")                                   ;

Los nombre en mayúscula y minúscula, cambiando el orden del filtro, e decir todo lo que se me ocurrio , pero nada.

Como funciona y demás y con los clientes colgados del cuello,  tuve que declinar la reina,  y perder la batalla, pero no la guerra, y si del cielo te caen limones tienes que aprender hacer limonada.

Replantee el problema , muy a mi pesar tenia que combinar mi dulce y puro sistema java , por un hibrido, algunos puristas nos podemos sentir ofendidos por lo que hice , pero hay veces que hay que someterse a los rigores de la realidad.

El sistema seria asi:

1. El cliente PHP puro, del cual no tenia ni idea como se bebia ni como se comía, pero hay hifue-mil foros sobre como se conecta Magneto en PHP y decían que a todos les funcionaba, pensé porque a mi no ?


2. Necesita como ejecutar PHP, como script

3. Crear un bean que llamara el script PHP y guardara la información en java

4. Colocar este bean para ser consumido por opencms.

Los dos últimos tenia idea  de como hacerlo de los dos primeros a consultar jefe.

Bueno para no hacer mas largo el cuento, efectivamente en uno o dos foros que consulte daban la forma de bajar la información de Magento con pelos y señales Muy agredecido con los señores de PHP Para este oficio tiene una buena herramienta hay que decirlo

El scrip después de algunos intentos , mal encaminados de mi parte por lo buñuelo en php quedó así, me imagino que los que saben Php , pueden ver este código y decir pero que bárbaro, como hizo eso , bueno mis disculpas , pero este mamaracho de principiante PHP camino sin ningún problema
Con filtros y demás y la cosa esta, vuela.

Desde luego primero tuve que cargar el php a mi sistema en este caso centos 6.2
con yum -y install php*

y aparte.
Para que el php pudiera reconecer el webservice.

     yum -y install php-soap*

Este ultimo favor verificarlo lo encontre de diversa formas (phpSoap, php_soap, etc)
Me funciono a mi el que dejo en este blog.
----------------------------------------------------------------------------------------------------------------------
 <?php

  // Este script fue grabado en /usr/bin/Sos.php para que quede
  // en la ruta de ejecucion de comando de linux.
  // para poder ser ejecutado desde la linea de comando de java


//Url de la conexión

    $wsdl   = "http://empresaT.com/index.php/api/soap/?wsdl";
    $client = new SoapClient($wsdl);

//Login
    $session = $client->login("miCuenta", "miClave");

//Lista de pedidos


// El argumento del correo a buscar se encuentra en la variable
//externa $argv[1]
//  Ejemplo $correo    = "%miUsuario@gmail.com%";
// que se pasa en linea de comando
// El sistema debe filtrar el correo del usuario pasado como parámetro y
que el estado de
// la transacción este pendiente de pago  status=pending_payment

  $correo    =  $argv[1]       ;
  $condicion1 = array (
                       'like' => $correo
                     );
 
   $pedidos =
   $client->call($session,"sales_order.list",array($filtro));

//Impresión Muestra toda la lista de pedidos pendientes de pago
// print_r($pedidos);
// lo use para depurar el código

for ($i=0 ; $i<count($pedidos) ; $i++)
  {
    $salida = $pedidos[$i];
    while (list ($clave,$valor) = each($salida))
       {
          if ($clave == "base_grand_total")
            {
              $sos = $valor           . ",";
            }
          if ($clave == "increment_id")
            {
              $sos = $sos . $valor    . ",";
            }
          if ($clave == "updated_at")
            {
              $sos = $sos . $valor    . "&";
            }
  };

echo $sos;

//Logout
$client->endSession($session);



?>
-----------------------------------------------------------------------------------------------------------------
 El comando echo pone una variable cadena a la salida del script
y unos magos de php indicaban que uno podía capturar los parámetros
de entrada con $variable =  $argv[1]  ; por ejemplo
Lo demás fue vilmente copiado de los foros y ajustado a la necesidad.
El uso  while (list ($clave,$valor) = each($salida)) me facilitó ampliamente
la depuración de los campos de interés, que como dije antes son mas de 100

base_grand_total , donde Magente guarda el valor a pagar
increment_id , donde tiene las ordenes de pedido de mi interés
updated_at donde esta la fecha de la transacción.

Ya armado con este script el cual se ejecuto sin problema mediante el
CLI de Php con el comando:

# php  -f sos.php

Esto fue necesario revisarlo cuando inserte este comando en bean pues no encontraba mi comando sos.php , y haciendo una pequeña suposición pensé si este script es como un comando del shell , como parece trabajar , lo voy a copiar en /usr/bin.
Y si señor funciono, pero eso lo vemos en el siguiente programa del bean.
-----------------------------------------------------------------------------------------------------------------------

31/05/2012
*/

import java.io.*   ;
import java.util.* ;


public class sosBean
{
    private String email           = ""                                     ;
    private String movimiento      = ""                                     ;
    private String timeStamp       = ""                                     ;


    //  Consulta de Pedidos en EmpresaT
    //  Solicita el correo del usuario y regresa un string con:
    //  Numero del Pedido, correo solicitado, valor de la transaccion(s)
    //  Fecha del movimiento ej:


    public sosBean()
    {
    }

    public void setMovimiento(String _movimiento)
    {

    String correo    = _movimiento                                     ;

    BufferedReader stdOut                                                  ;
    BufferedReader stdErr                                                  ;

    Runtime command  = Runtime.getRuntime()                ;
    Process proceso  = null                                                 ;
    String  consulta = "/usr/bin/php -f /usr/bin/sos.php "  ;
    consulta+= "%"                                                             ;
    consulta+= correo.trim()                                             ;
    consulta+="%"                                                             ;   
     try
          {

          _movimiento = ""                                                    ;

          proceso = command.exec(consulta)                       ;
          proceso.waitFor()                                                   ;

          InputStream is = proceso.getInputStream()                    ;
          stdOut = new BufferedReader(new InputStreamReader(is))       ;
          is = proceso.getErrorStream()                                ;
          stdErr = new BufferedReader(new InputStreamReader(is))       ;

          int i = 0                                                    ;
          String line = new String()                        ;
    public void setMovimiento(String _movimiento)
    {

    String correo    = _movimiento                                  ;
    BufferedReader stdOut                                              ;
    BufferedReader stdErr                                              ;

    Runtime command  = Runtime.getRuntime()                ;
    Process proceso  = null                                                 ;
    String  consulta = "/usr/bin/php -f /usr/bin/Tdm.php "  ;
    consulta+= "%"                                             ;
    consulta+= correo.trim()                              ;
    consulta+="%"                                              ;
          for (i=0 ; (line = stdOut.readLine()) != null ;)
              {
              if (line.length() > 0 )
                  {
                  i++                            ;
                  _movimiento += line ;
                  }
              }
          }
          catch (Exception e)
          {
          _movimiento = "Error de Ejecucion:"                     ;
          _movimiento+= e.toString()                                   ;
          }
      movimiento = _movimiento                                         ;
    }
    public String getMovimiento()
    {
    return (movimiento)                                                      ;
    }

    public void setTimeStamp(String _timeStamp)
    {
    timeStamp = _timeStamp                                          ;
        {
            return (timeStamp)                                              ;
        }
    }
------------------------------------------------------------------------------------------------------------------------------
El valor del correo de mi cliento se le pasa al bean como argumento: 
setBean( String _movimiento)
en donde la variable _movimiento del bean guarda el correo a consultar

Y se asigna en el bean mediante la asignación :

String correo    = _movimiento   ;
 

Se deber resaltar en este bean el uso del comando

   Runtime command  = Runtime.getRuntime()     

Que permite ejecutar script de linea de comando del shell del sistema operativo
al hacer  sos.php un script de comando podia ser ejecurtado en lñnea de comando asi:

consulta = "/usr/bin/php -f /usr/bin/sos.php "    ;

Notar las rutas totalmente cualificadas tanto del php como del script sos.php,
asi me funciono previa copia del script sos.php en /usr/bin

Pasamos el argumento correo que ingreso como parámetro del setBean :
al comando sos.php, entre % , porque se observa en el script que uso una consulta de la base datos con el comando like ya que el igual (=) me puso
algún problema con algunos correos


    consulta+="%"                                              ;
    consulta+=    correo.trim()                           ;
    consulta+="%"     

Las  dos lineas siguientes hacen la magia , la primera ejecuta el comando y la segunda obliga a que el sistema espere hasta que el comando haya concluido.

    proceso = command.exec(consulta)                       ;
    proceso.waitFor()                                                    ;


Las siguientes lineas que operan sobre una instancia de proceso , recuperan los valores que el comando echo de sos.php retorna a la linea de comando

         InputStream is = proceso.getInputStream()                    ;
          stdOut = new BufferedReader(new InputStreamReader(is))       ;
          is = proceso.getErrorStream()                                ;
          stdErr = new BufferedReader(new InputStreamReader(is))       ;

En stdOut están los valores pasados como cadena desde el script sos.php separados por el signo "&" que se ve en el script sos.php al final de la cadena
if ($clave == "updated_at")
            {
              $sos = $sos . $valor    . "&";
            }
 El valor de la cadena puede ser recupurado por el bean : getMovimiento()

Ahora como necesitamos usar este bean el opencms, es necesario copiarlo
en la ruta correcta.

copiamos el bean sos.java en:
suponiendo que se tiene instalado opencms en la ruta:
 /usr/local/tomcat/webapps/opencms

# /usr/local/tomcat/webapps/opencms/WEB-INF/classes/beans/ 

En el siguiente link a mi blog hay una pequeña guía de los pasos para habilitar el bean que acabamos de crear en opencms.
 



Comentarios

Entradas populares