Integración Java y Zoho CRM (Eclipse Mars)

Antes de empezar con el código…

¿Qué es un CRM?

CRM (Customer Relationship Management) es la sigla que se utiliza para definir una estrategia de negocio enfocada al cliente, en la que el objetivo es reunir la mayor cantidad posible de información sobre los clientes para generar relaciones a largo plazo y aumentar así su grado de satisfacción

¿ Qué es Zoho CRM ?

Zoho CRM le ofrece una visión completa del ciclo de vida del cliente con el objetivo de establecer en la organización un único sistema de negocio para ventas, marketing, servicio de soporte al cliente y todos los procesos llevados a cabo por el área comercial.

Zoho CRM recopila y gestiona la información de contactos y clientes, creando un histórico para dar un mayor valor a su oferta. Esto permite mejorar la calidad del trato y satisfacción ofreciendo a sus clientes la solución que más se adecue a sus necesidades y fidelizando a estos en el tiempo. Y a la hora de medir resultados, la aplicación genera gráficos, pronósticos e informes personalizados de forma sencilla.

Para integrar Java con Zoho CRM tendremos que añadir las librerías de la api de Zoho.

https://zohoreportsapi.wiki.zoho.com/Java-Client-Library.html

Los jars que deberemos añadir a nuestro proyecto Java son:

  • Commons-codec-1.7.jar – Zoho/lib
  • Commons-httpclient-3.1.jar – Zoho/lib
  • Commons-logging-api.jar – Zoho/lib
  • Csv.jar – Zoho/Lib
  • ZohoReportAPICliente.jar – Zoho/lib

zoho1.png

A continuación, tendremos que generar un TOKEN, con nuestro usuario, para poder atacar a la API de Zoho. (tendremos que crear una cuenta y tener un usuario disponible para poder continuar).

https://www.zoho.com/crm/help/api/using-authentication-token.html#Generate_Auth_Token

Utilizaremos el método de generar el Token a través de URL:

 

EMAIL_ID Specify your Zoho CRM Username or Email ID
scope Specify the value as ZohoCRM/crmapi
PASSWORD Specify your Zoho CRM Password
DISPLAY_NAME Specify the Application Name that describes the purpose of using this AuthToken. For example, «MailChimp» or «Google Apps»

Tras atacar a la url de generación de key, obtendremos en el navegador una respuesta similar a la siguiente:

 

#Wed Feb 29 03:07:33 PST 2012
AUTHTOKEN=bad18eba1ff45jk7858b8ae88a77fa30
RESULT=TRUE

La KEY que hemos generado tendremos que añadirla a nuestro proyecto Java. Crearemos una clase Config.java, donde almacenaremos las variables para poder trabajar con el CRM.

Captura1.png

Una vez tenemos creada la clase Config, vamos a crear algunas clases para poder explotar la API de Zoho CRM.

Para obtener los usuarios registrados y activos, podríamos usar la siguiente clase:

Captura2

Un ejemplo de llamada a la clase GetUsers:
GetUsers.getUsers(«1», «1», «AdminUsers»);

Respuesta:

<?xml version=«1.0» encoding=«UTF-8»?>
<users>
  <user id=«1980680000000099003» zuid=«629741395» website=«null» mobile=«null» fax=«null» phone=«989514518» street=«street 012» city=«Madrid» state=«Madrid» country=«Spain» zip=«null» language=«es_ES» timezone=«PST8PDT» email=«alexortizcamarasa@gmail.com» role=«CEO» profile=«Administrator» status=«active» confirm=«true»><![CDATA[aortiz]]></user>
</users>

Otro ejemplo, para obtener los módulos del CRM:

Captura4.png

Ejemplo de llamada:

GetModules.getModules(«api»);

Ejemplo de respuesta:

<?xml version=«1.0» encoding=«UTF-8»?>
<response uri=«/crm/private/xml/Info/getModules»>
  <result>
     <row no=«1» id=«1980680000000002175» pl=«Posibles clientes» sl=«Posible cliente» gt=«1»>Leads</row>
     <row no=«2» id=«1980680000000002177» pl=«Cuentas» sl=«Cuenta» gt=«1»>Accounts</row>
     <row no=«3» id=«1980680000000002179» pl=«Contactos» sl=«Contacto» gt=«1»>Contacts</row>
     <row no=«4» id=«1980680000000002181» pl=«Oportunidades» sl=«Oportunidad» gt=«1»>Potentials</row>
     <row no=«5» id=«1980680000000002193» pl=«Tareas» sl=«Tarea» gt=«1»>Tasks</row>
     <row no=«6» id=«1980680000000002195» pl=«Eventos» sl=«Evento» gt=«1»>Events</row>
     <row no=«7» id=«1980680000000033015» pl=«Llamadas» sl=«Llamada» gt=«1»>Calls</row>
     <row no=«8» id=«1980680000000002183» pl=«Campañas» sl=«Campaña» gt=«1»>Campaigns</row>
  </result>
</response>

También podemos crear, buscar, editar y eliminar (CRUD) elementos del modelo de datos de nuestro CRM, por ejemplo, en la siguiente clase, insertamos cuentas:

Captura5.png
Ejemplo de llamada:

String xmlAccounts = «<Accounts><row no=\»1\»><FL val=\»Account Name\»>Zillum</FL><FL val=\»Website\»>www.zillum.com</FL><FL val=\»Last Name\»>James</FL>»
+ «<FL val=\»Employees\»>200</FL><FL val=\»Ownership\»>Private</FL><FL val=\»Industry\»>Real estate</FL><FL val=\»Fax\»>99999999</FL>»
+ «<FL val=\»Annual Revenue\»>20000000</FL></row></Accounts>»;
InsertRecords.insertRecords(xmlAccounts, «true», «1», «false», «1», «4»);

Si accedemos al CRM podemos ver como los registros se han ido creando y como aparecen en el apartado de Auditoría de la aplicación:

Captura7.png

Captura6.png

Por último vamos a ver un ejemplo de cómo buscar registros usando la API de Zoho:

Captura8.png

Ejemplo de llamada:

SearchRecords.searchRecords(«(Phone:999999999)»);

Ejemplo de respuesta:

<?xml version=«1.0» encoding=«UTF-8»?>
<response uri=«/crm/private/xml/Leads/searchRecords»>
  <result>
     <Leads>
        <row no=«1»>
           <FL val=«LEADID»>1980680000000102025</FL>
           <FL val=«SMOWNERID»>1980680000000099003</FL>
           <FL val=«Lead Owner»><![CDATA[aortiz]]></FL>
           <FL val=«First Name»><![CDATA[Alex]]></FL>
           <FL val=«Last Name»><![CDATA[Ortiz]]></FL>
           <FL val=«Email»><![CDATA[test@test.com]]></FL>
           <FL val=«Phone»><![CDATA[999999999]]></FL>
           <FL val=«Fax»><![CDATA[99999999]]></FL>
           <FL val=«Mobile»><![CDATA[99989989]]></FL>
           <FL val=«No of Employees»><![CDATA[0]]></FL>
           <FL val=«Annual Revenue»><![CDATA[0]]></FL>
           <FL val=«SMCREATORID»>1980680000000099003</FL>
           <FL val=«Created By»><![CDATA[aortiz]]></FL>
           <FL val=«MODIFIEDBY»>1980680000000099003</FL>
           <FL val=«Modified By»><![CDATA[aortiz]]></FL>
           <FL val=«Created Time»><![CDATA[2016-06-14 03:00:28]]></FL>
           <FL val=«Modified Time»><![CDATA[2016-06-14 03:01:16]]></FL>
           <FL val=«Email Opt Out»><![CDATA[false]]></FL>
           <FL val=«Last Activity Time»><![CDATA[2016-06-14 03:01:16]]></FL>
        </row>
     </Leads>
  </result>
</response>

En el siguiente enlace se pueden consultar los métodos disponibles, ver ejemplos, etc.. :
Consultar la API de Zoho CRM:
https://www.zoho.com/crm/help/api/api-methods.html

Para descargar proyecto de ejemplo (cambiar valores en Config.java):
Zoho.jar

En otro post veremos cómo podemos atacar a la API de Zoho Reports, para obtener informes, gráficos, etc…

Despliegue ADF 12c en Glassfish4

Instalación y configuración de Glassfish 4

Instalación

Instalación Windows (Windows 8)

Para completar la instalación del servidor de aplicaciones Glassfish4 en un equipo con sistema operativo Windows tendremos que realizar los siguientes pasos:

Descomprimir el archivo latest-glassfish.zip en C.

Para arrancar el servidor navegamos hasta el directorio bin desde la consola de comandos y ejecutamos el siguiente comando:

C:\glassfish4\glassfish\bin asadmin start-domain

La primera vez que arrancamos el servidor, se crea el directorio …/domains/domain1

NOTA: Hay que tener en cuenta tener un JDK compatible con la versión de GlassFish que se va a instalar.

Instalación RedHat

Será necesario tener instalado Java y alguna herramienta de descompresión de archivos.

Por ejemplo:

  • yum install java-1.8.0

  • yum install unzip

  1. Descomprimir el archivo latest-glassfish.zip unzip latest-glassfish.zip

  2. Para arrancar el servidor navegamos hasta el directorio bin desde la consola de comandos y ejecutamos el siguiente comando:

    1. cd glassfish4\glassfish\bin

    2. ./asadmin start-domain

La primera vez que arrancamos el servidor, se crea el directorio …/domains/domain1

Para poder acceder de forma remota será necesario crear un usuario con contraseña. A continuación vamos a crear una contraseña válida para el usuario “admin”:

./asadmin change-admin-password –user admin

Para que se pueda acceder a la consola de forma remota (si fuera necesario):

./asadmin –host localhost –port 4848 enable-secure-admin

Configuración

Descomprimimos el contenido de adf-essentials.zip en:

  • glassfish4/glassfish/domains/domain1/lib mediante unzip -j

IMPORTANTE: hay que usar la función -j para descomprimir todos los jars sin estructura de directorios. Todos los jars tienen que estar en …\domain1\lib

  • De todos los jars de adf-essentials movemos el jar ojdbc7dms.jar al directorio lib general del servidor glassfish4\glassfish\lib.

 

Configuración JVM:

Configurations > server-config > JVM Settings > JVM Options

Añadimos las siguientes propiedades:

  • -Doracle.jdbc.autoCommitSpecCompliant=false
  • -Doracle.mds.cache=simple
  • -XX:MaxPermSize=512m (debe tener el máximo posible)

Captura74.png

 

Captura1.png

JDBC Connection Pools

Resources > JDBC > JDBC Connection Pools

Añadimos una nueva conexión con las siguientes propiedades: (datos de ejemplo, sustituir por los reales los que están en rojo)

    • PoolName: DemoGlassfish
    • Resource Type: javax.sql.DataSource
    • Datasource Classname: oracle.jdbc.xa.client.OracleXADataSource

    • Url: jdbc:oracle:thin:@demo:1521:Desarrollo01
    • User: demo
    • Password: *******

Captura3

Captura4.png

Captura5.png

 

JDBC Resources

Resources > JDBC > JDBC Resources

  • JNDI Name: jdbc/DemoGlassfishDS (Este nombre lo usaremos más adelante para configurar nuestra aplicación ADF)
  • ConnectionPool: DemoGlassfish (Nombre de la conexión que hemos creado en el paso anterior).

ZeleyOxwl3tezsRB7M1yYBCy0cEoYIFF-5ivx3hQEvlOXlzzuq2_k9B_SaiRT77uvoxaU9wMVbZZFL6H8-kNCId3tmvsV2yDhbr58qzTc7lCpJb0iDXdLaz1ZGS-r3DZTv1sE2Q1.png

xsbQ4kZB2e1vm3J7ny0nMmZ-ST0RUVVcqGHjZC6cRHWZTlsXNjXru9wp-VRQYCdo3uR4yT1wy9Uoz7p2YZjUXEoUvWfJThlhXoYNUQG4X7rMxWMCa04wQwnds-btAFhuZB0T-7Qu.png

Configuración y Deployment de aplicación ADF

Configuración

A continuación vamos a configurar una aplicación ADF en JDeveloper para que pueda ser desplegada en un servidor GlassFish 4 (configurado previamente).

Model

Una vez configurado el servidor Glassfish y creadas las conexiones de base de datos (JDBC Connections Pools y JDBC Resources) tenemos que adaptar nuestra aplicación para que use el jdbc de Glassfish.

En nuestro proyecto Model seleccionamos el AppModule y en la pestaña Configurations, seleccionamos y editamos las propiedades de la configuración AppModuleLocal.

Captura74

Captura1

En la configuración Connection Type seleccionaremos JDBC DataSource y en Datasource Name introducimos el nombre del JDBC Resource que hemos configurado previamente en el servidor Glassfish.

Captura2

ViewController

Será necesario incluir algunas propiedades en el proyecto ViewController de nuestra aplicación para que funcione en Glassfish.

Añadiremos las siguientes propiedades al fichero de configuración web.xml que se encuentra en ViewController > Web Content > WEB-INF > web.xml.

Captura3.png

<context-param>

       <param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name>

       <param-value>*.jsf;*.xhtml,*.jspx,*.jsp</param-value>

   </context-param>

   <context-param>

       <param-name>javax.faces.DEFAULT_SUFFIX</param-name>

       <param-value>.jsf</param-value>

   </context-param>

OPCIONAL pero recomendable. Añadir una página de inicio en nuestra aplicación:

  • faces: quiere decir que la página se encuentra en un taskFlow y por tanto la navegación modelada mediante flujos está activa.
  • listadoAreas: identificador de la página. Cómo se llama la página jsf o jspx sin extensión en el taskFlow. Por norma general vamos a mantener siempre el mismo nombre en el archivo fuente y en nodo de los taskFlow.

   <welcome-file-list>

       <welcome-file>faces/listadoAreas</welcome-file>

   </welcome-file-list>

Configuración del WAR

Sobre el proyecto ViewController de nuestra aplicación pulsamos botón derecho y seleccionamos la opción New > From Gallery. En la ventana que se muestra buscaremos la opción General > Deployment Profiles > WAR File.

Captura4

Se mostrará la siguiente ventana, en la que tendremos que indicar el nombre del perfil de despliegue:

Captura5.png

A continuación configuraremos el perfil para que el WAR generado sea compatible con GlassFish.

  • Seleccionamos la opción File Groups > WEB-INF/lib > Contributors. En el listado de librerías que se muestran en la parte derecha de la ventana, además de las que ya hay seleccionadas, tendremos que seleccionar las siguientes:
    • ADF Faces Runtime 11
    • JSTL 1.2

Captura6.png

Seleccionamos la opción File Groups > Web Files > Filters > WEB-INF y desmarcamos la opción weblogic.xml.

Por último, en la opción Platform, seleccionamos Glassfish 3.1 como plataforma de despliegue por defecto.

Captura7.png

El nuevo perfil de despliegue se mostrará en las propiedades del proyecto ViewController, en la opción Deployment.

Captura8.png

Configuración del EAR

Una vez configurado el despliegue del proyecto ViewController de nuestra aplicación, vamos a proceder a configurar el despliegue de la aplicación para que sea compatible con Glassfish 4.

Sobre el menú Application seleccionamos la opción New. En la ventana New Gallery que se muestra buscaremos la opción General > Deployment Profiles > EAR File

Captura9.png

En la ventana que se muestra a continuación introduciremos un nombre para el perfil de despliegue.

Captura10.png

A continuación configuraremos el perfil para que el EAR generado sea compatible con GlassFish.

  • En la opción File Groups > Application Descriptors > Filters desmarcar la opción weblogic-application.xml.

Captura12.png

  • En la opción Application Assembly seleccionamos el perfil de despliegue WAR del proyecto ViewController que hemos generado en la fase anterior.

Captura13.png

Por último, en la opción Platform, seleccionamos Glassfish 3.1 como plataforma de despliegue por defecto.

Captura14.png

El nuevo perfil de despliegue se mostrará en las propiedades de la aplicación, en la opción Deployment.

Captura15.png

Deployment

Para desplegar la aplicación y generar el EAR que más adelante pondremos en el servidor Glassfish, seleccionamos la opción Application > Deploy y de todas las opciones disponibles, seleccionamos el perfil de despliegue que acabamos de crear. Se mostrará una ventana para seleccionar el tipo de despliegue. Seleccionaremos Deploy to EAR.

Captura16.png

En la consola de despliegue de JDeveloper (Deployment –  Log) se mostrará el proceso de despliegue y si hay errores o se realiza correctamente. También nos indica dónde se ha generador el EAR.

 

[09:48:55 AM] —-  Deployment started.  —-

[09:48:55 AM] Target platform is  (Glassfish 3.1).

[09:48:55 AM] Running dependency analysis…

[09:48:55 AM] Building…

[09:49:11 AM] Deploying 2 profiles…

[09:49:11 AM] ADF shared library is not available, implicitly deploying library ADF Controller Schema

[09:49:11 AM] ADF shared library is not available, implicitly deploying library ADF Controller Runtime

[09:49:11 AM] ADF shared library is not available, implicitly deploying library ADF Page Flow Runtime

[09:49:11 AM] Wrote Web Application Module to C:\JDeveloper\mywork\DemoGlassfish\ViewController\deploy\DemoGlassfish2.war

[09:49:12 AM] Wrote Enterprise Application Module to C:\JDeveloper\mywork\DemoGlassfish\deploy\Glassfish2.ear

[09:49:12 AM] Elapsed time for deployment:  18 seconds

[09:49:12 AM] —-  Deployment finished.  —-

 

Por último, para desplegar el EAR en el servidor GlassFish, accedemos a la consola del servidor:

http://localhost:4848/common/index.jsf

En la pestaña Applications, seleccionamos la opción Deploy y seleccionamos el EAR que acabamos de generar desde JDeveloper.

Captura17.png

Captura18.png

Captura19.png

Captura20

Debug ADF + Glassfish 4 (remoto)

Para poder ejecutar una aplicación ADF en modo debug con Glassfish ejecutaremos el servidor con la opción debug = true:

asadmin start-domain –debug=true

Si entramos en la consola de Glassfish y en la pestaña “General information” podremos ver que el puerto por defecto del modo Debug es el 9009:

Debug: Enabled on Port: 9009

Captura74

A continuación, en nuestra aplicación, en el proyecto ViewController tendremos que editar las siguientes opciones en «Project Properties>Run/Debug«:

Captura1

Marcaremos la opción «Remote Debugging» y cambiaremos el puerto para el debug remoto a 9009:

Captura2

Captura3

Por último arrancamos nuestra aplicación en modo Debug y nos aparecerá el siguiente popup: (por defecto aparecerá el puerto que hemos indicado en el paso anterior)

Captura4

Si la conexión con el servidor remoto se ha realizado correctamente se mostrará el siguiente mensaje por consola:

Captura5

 

 

Resolviendo Bug ADF 12c + Trinidad + Glassfish 4.1 (trindiad-impl.jar)

Existe un bug en la última versión de ADF Studio Edition Version 12.2.1.0.0 y Glassfish 4.1 que no permite subir archivos utilizando el componente af:inputFile. El error se produce en la clase MultipartFormHandler.class de trinidad-impl.jar (ver. 2.0.0).

Si estamos utilizando af:inputFile con un af:form y la propiedad usesUpload a true.

<af:form id=»f1″ usesUpload=»true»>

<af:inputFile label=»Archivo» id=»dc_if1″ />

</af:form>

Cuando intentamos subir un archivo a nuestra aplicación, Glassfish devuelve el siguiente error:

java.io.EOFException at org.apache.myfaces.trinidadinternal.share.util.MultipartFormHandler.

_skipBoundary(MultipartFormHandler.java:229) at org.apache.myfaces.trinidadinternal.share.util.MultipartFormHandler.

<init>(MultipartFormHandler.java:102) at org.apache.myfaces.trinidadinternal.share.util.MultipartFormHandler.<init>(MultipartFormHandler.java:75) at org.apache.myfaces.trinidadinternal.config.upload.FileUploadConfiguratorImpl.

beginRequest(FileUploadConfiguratorImpl.java:139) at org.apache.myfaces.trinidadinternal.config.GlobalConfiguratorImpl.

_startConfiguratorServiceRequest(GlobalConfiguratorImpl.java:746) at org.apache.myfaces.trinidadinternal.config.GlobalConfiguratorImpl.

beginRequest(GlobalConfiguratorImpl.java:227) at org.apache.myfaces.trinidadinternal.webapp.TrinidadFilterImpl.doFilter(TrinidadFilterImpl.java:184) at org.apache.myfaces.trinidad.webapp.TrinidadFilter.doFilter(TrinidadFilter.java:92) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)

El método _parseBoundary(String ), no está devolviendo la cadena correcta. En algunos casos al parámetro boundary que devuelve se le está sumando la cadena “charset=UTF-8”.

MultipartFormHandler.java

Método original:

Captura1
Para resolverlo, descargaremos la versión de trinidad-impl.jar que está usando ADF (trinidad-impl-2.0.0-sources.jar.zip). Y añadiremos el siguiente parche:

Captura2

Donde nos quedamos con el valor de boundary descartando cualquier string que se añada después (“charset=UTF-8” en nuestro caso).

Compilamos trinidad-impl y sustituimos el jar en el despliegue de nuestra aplicación.

trinidad-impl.java

trinidad-impl-2.0.0-sources.jar.zip

 

Hilos abiertos sobre el bug:

https://community.oracle.com/message/13845423#13845423

https://community.oracle.com/message/13845425#13845425

https://community.oracle.com/message/13845473#13845473

https://community.oracle.com/message/13845424#13845424

https://community.oracle.com/message/13845421#13845421