jueves, 9 de diciembre de 2021

[JD Edwards - BSSV] JD Edwards - Salesforce integration: Making proxy package JAVA with WSIMPORT tool

Hi friend,

Recently, I've done a JDE with Salesforce Cloud integration, through BSSV both inbound and outbound communication with Soap technology. Salesforce use Apex (Oracle Application Express) for integrations

Integración JDE - Salesforce



One of the main problems that I found was generate proxy client, the  Organization WSDL  has a lot of methods (this service is the principal , and it is used for all access related: login, logout, sessions, userinfo, etc), and besides that when trying to generate proxy client in JDeveloper 12c (12.2.1.3.0) it gave errors to namespaces conflicts.

So, I decided try alternate path, using JAVA wsimport tool, it tool from the file or IP WSDL will generate us a package java .jar with all classes and method services, it package we could import to a ower bssv project as external library and works comfortable.

You can look a lot of information about the use of it java tool:

https://docs.oracle.com/javase/7/docs/technotes/tools/share/wsimport.html

https://www.ibm.com/support/knowledgecenter/es/SSEQTP_9.0.5/com.ibm.websphere.base.doc/ae/twbs_jaxwsclientfromwsdl.html

https://www.ibm.com/support/knowledgecenter/es/SSEQTP_9.0.5/com.ibm.websphere.base.doc/ae/rwbs_wsimport.html

https://mkyong.com/webservices/jax-ws/jax-ws-wsimport-tool-example/

http://chuwiki.chuidiang.org/index.php?title=Ejemplo_sencillo_de_web_service_con_jax-ws


And more specific for Salesforce service:

https://stackoverflow.com/questions/2322953/jax-ws-adding-soap-headers

https://udby.com/archives/132

I recommend, java version it's the same for wsimport and JDeveloper configured for your JDE enviroment ( it can do directly with the java executable version in JDE machine or add java version path on the PATH operative system).


Execution example:

wsimport -b bindings.xjb -keep -B-XautoNameResolution -XadditionalHeaders -Xdebug OrganizationDEV.wsdl -clientjar SalesForceOrganizationDEVWSDLConnector.jar 

Donde

wsimport: java  command for class generation from wsdl

-b: specify link files jaxws/jaxb or additional schemes

bindings.xjb: link file or additional schemes

-keep: keep generated files 

-B-XautoNameResolution: JAXB instructions to automatically resolve names conflicts.

-XadditionalHeaders: generates header parameters in request methods

-Xdebug: print debug information

OrganizationDEV.wsdl: wsdl file with service information

-clientjar: make jar file with artifacts generated together WSDL metadata for call web service.

SalesForceOrganizationDEVWSDLConnector.jar: jar file will generate with all java class and wsdl to project import.

bindings.xjb file will depends from namespaces and transformations to do.

bindings.xjb

<?xml version="1.0" encoding="UTF-8"?>

<bindings

    wsdlLocation="wsdlcalidad.wsdl"

    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"

    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema"

    xmlns="http://java.sun.com/xml/ns/jaxws">

    <bindings node="//xsd:schema[@targetNamespace='urn:sobject.enterprise.soap.sforce.com']">

      <jaxb:globalBindings generateElementProperty="false" underscoreBinding="asCharInWord"/>

    </bindings>

</bindings>


Other example:

<?xml version="1.0" encoding="UTF-8"?>

<bindings

    wsdlLocation="INTProducto_JDE.wsdl"

    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"

    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema"

    xmlns="http://java.sun.com/xml/ns/jaxws">

    <bindings node="//xsd:schema[@targetNamespace='http://soap.sforce.com/schemas/class/INTProducto_JDE']">

      <jaxb:globalBindings generateElementProperty="false" underscoreBinding="asCharInWord"/>

  <jaxb:schemaBindings>

        <jaxb:nameXmlTransform>

          <jaxb:typeName suffix="Type" />

        </jaxb:nameXmlTransform>

      </jaxb:schemaBindings>

    </bindings>

    <bindings node="//xsd:schema[@targetNamespace='http://soap.sforce.com/schemas/class/INTResponse']">

      <jaxb:globalBindings generateElementProperty="false" underscoreBinding="asCharInWord"/>

  <jaxb:schemaBindings>

        <jaxb:nameXmlTransform>

          <jaxb:typeName suffix="Type" />

        </jaxb:nameXmlTransform>

      </jaxb:schemaBindings>

    </bindings>

    <enableWrapperStyle>false</enableWrapperStyle>

    <enableAsyncMapping>false</enableAsyncMapping>

</bindings>

And finally, you import jar file to project, adding libraries for deploy and start to use classes and method to call service.

I hope it is useful for you friend.

Best regards.




jueves, 29 de julio de 2021

[JD Edwards - BSSV] Integración JDE - Salesforce: Crear proxy paquete JAVA con WSIMPORT

 Hola amigos,

Recientemente he realizado una integración de JDE con Salesforce Cloud, a través de BSSV tanto de entrada como de salida con Soap. Salesforce utiliza Apex para las integraciones.

Integración JDE - Salesforce

Uno de los problemas principales que me encontré fue al generar el proxy client, ya que el WSDL de Organization que se genera tiene una gran cantidad de métodos (éste servicio es el principal, y se utiliza para todo lo relacionado con el acceso: login, logout, sessions, userinfo, etc), y además al generar el proxy client en JDeveloper 12c (12.2.1.3.0) daba errores por conflictos en los namespaces.

Así que, decidí utilizar un camino alternativo, utilizando la herramienta de JAVA wsimport el cual a partir del archivo o dirección WSDL nos generará un paquete java .jar con las clases y métodos del servicio, el cual podremos importar a nuestro proyecto como una librería externa y trabajar cómodamente.

Podéis encontrar mucha información acerca del uso de ésta herramienta java:

https://docs.oracle.com/javase/7/docs/technotes/tools/share/wsimport.html

https://www.ibm.com/support/knowledgecenter/es/SSEQTP_9.0.5/com.ibm.websphere.base.doc/ae/twbs_jaxwsclientfromwsdl.html

https://www.ibm.com/support/knowledgecenter/es/SSEQTP_9.0.5/com.ibm.websphere.base.doc/ae/rwbs_wsimport.html

https://mkyong.com/webservices/jax-ws/jax-ws-wsimport-tool-example/

http://chuwiki.chuidiang.org/index.php?title=Ejemplo_sencillo_de_web_service_con_jax-ws


Y más específicos para servicios de Salesforce:

https://stackoverflow.com/questions/2322953/jax-ws-adding-soap-headers

https://udby.com/archives/132

Os recomiendo, que la versión java que utilicéis para wsimport sea la misma que utilice la versión del JDeveloper configurado para vuestro JDE (esto podréis hacerlo directamente con el ejecutable de la versión java instalado o añadiendo la ruta de la versión java sobre el PATH del sistema operativo).


Ejemplo ejecución:

wsimport -b bindings.xjb -keep -B-XautoNameResolution -XadditionalHeaders -Xdebug OrganizationDEV.wsdl -clientjar SalesForceOrganizationDEVWSDLConnector.jar 

Donde

wsimport: comando java para la generación de clases a partir de wsdl

-b: expecifica archivos de enlace jaxws/jaxb o esquemas adicionales

bindings.xjb: archivo de enlace o esquemas adicionales

-keep: mantiene los archivos generados

-B-XautoNameResolution: instrucción de JAXB para automáticamente resolver conflictos de nombres

-XadditionalHeaders: genera parámetros de cabecera en los métodos de la peticiones

-Xdebug: imprime la información de depuración

OrganizationDEV.wsdl: archivo wsdl con la información del servicio

-clientjar: crea el archivo jar de los artefactos generados junto con los metadatos WSDL necesarios para llamar al servicio web.

SalesForceOrganizationDEVWSDLConnector.jar: archivo jar a generar con todas las clases java y wsdl para importar al proyecto.

El archivo bindings.xjb dependerá de los namespaces y transformaciones a realizar.

bindings.xjb

<?xml version="1.0" encoding="UTF-8"?>

<bindings

    wsdlLocation="wsdlcalidad.wsdl"

    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"

    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema"

    xmlns="http://java.sun.com/xml/ns/jaxws">

    <bindings node="//xsd:schema[@targetNamespace='urn:sobject.enterprise.soap.sforce.com']">

      <jaxb:globalBindings generateElementProperty="false" underscoreBinding="asCharInWord"/>

    </bindings>

</bindings>


Otro ejemplo:

<?xml version="1.0" encoding="UTF-8"?>

<bindings

    wsdlLocation="INTProducto_JDE.wsdl"

    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"

    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

    xmlns:xsd="http://www.w3.org/2001/XMLSchema"

    xmlns="http://java.sun.com/xml/ns/jaxws">

    <bindings node="//xsd:schema[@targetNamespace='http://soap.sforce.com/schemas/class/INTProducto_JDE']">

      <jaxb:globalBindings generateElementProperty="false" underscoreBinding="asCharInWord"/>

  <jaxb:schemaBindings>

        <jaxb:nameXmlTransform>

          <jaxb:typeName suffix="Type" />

        </jaxb:nameXmlTransform>

      </jaxb:schemaBindings>

    </bindings>

    <bindings node="//xsd:schema[@targetNamespace='http://soap.sforce.com/schemas/class/INTResponse']">

      <jaxb:globalBindings generateElementProperty="false" underscoreBinding="asCharInWord"/>

  <jaxb:schemaBindings>

        <jaxb:nameXmlTransform>

          <jaxb:typeName suffix="Type" />

        </jaxb:nameXmlTransform>

      </jaxb:schemaBindings>

    </bindings>

    <enableWrapperStyle>false</enableWrapperStyle>

    <enableAsyncMapping>false</enableAsyncMapping>

</bindings>

Y por último, importar el archivo .jar al proyecto, añadirlo a las librerías para el despliegue y empezar a utilizar las clases y métodos para la llamada al servicio.

Espero os sea útil.

Un saludo.




jueves, 25 de febrero de 2021

[JD Edwards - BSSV] Importar librería JAVA externa (ESP)

 Hola amigos,

En ocasiones, nos encontramos con la necesidad de extender la funcionalidad de nuestro JDE y muchas funcionalidades nos la encontramos en paquetes o librerías externas JAVA ya que es uno de los lenguajes y plataformas más extendidos. Por ejemplo, recientemente trabajé en un proyecto para implementar códigos bidimensionales QR. Entonces, ¿cuál es la solución?


Pues utilizamos una librería JAVA para facilitar la codificación, en éste caso una de IdAutomation que es de pago, pero hay otras de Google (Zxing) y otras muchas open source, depende cada caso y uso.
Pues bien, éste proveedor facilita una librería java en el cuál tiene una clase y un método que le pasamos el string a codificar y nos devuelve un array codificado. Posteriormente, a éste array le ponemos una fuente y ya tenemos nuestro código QR codificado. Fácil ¿verdad?

Entonces, generamos nuestro objeto BSSV (y no nos olvidemos nuestra BSFN en C para luego comunicarnos desde nuestro report o aplicación), con nuestra clase y método principal. Pero ¿Cómo importamos nuestra librería en nuestro entorno JDeveloper

1. Sobre nuestro proyecto, pulsamos botón derecho y en el menú Project Properties...:

2. Pulsamos sobre el menú en Libraries and Classpath, y dentro de éste sobre Add JAR/Directory:


3. Seleccionamos nuestra librería (recomiendo dejarla en la ruta JDE system\Classes (y luego explico el motivo)

4. Pulsamos sobre Open/Abrir, se nos añade a nuestro proyecto

5. Pulsamos OK, y guardamos el proyecto. Ya podremos utilizar las clases y métodos de la librería externa importándolas a nuestro código.

               boolean bestMask = true;           // Best pattern mask
               
               String resultQREncode = qre.FontEncode(dataToEncode, applyTilde, encodingMode, errorCorrectionLevel, version, bestMask);
               internalVO.setSzQREncodedData(resultQREncode);
               
               printMsg(context, "Encoded => ");
               printMsg(context, resultQREncode);

Y ya tendríamos todo listo en nuestro proyecto!

Para desplegar, tenemos que configurar a nivel de sistema que usamos una librería externa para que a la hora de compilar y que genere el paquete de despliegue, importe nuestra librería. Ésta configuración se realiza en el servidor Deploy (aunque yo también la configuro en mi cliente pesado).

1. Copiamos nuestra librería en la carpeta system\Classes de nuestra instalación:

2. Modificamos el fichero sbffoundation.ini dentro de la misma carpeta, en la sección [Foundation] y añadimos una línea con "LIB" + "siguiente secuencia" + "=" + "Nombre de nuestra librería"

Y con esto ya tendríamos nuestro proyecto de BSSV con una librería externa lista para desplegar!

PD: he utilizado librería externa también para código Datamatrix, para integrar con Webcenter Content a través de RIDC, y recientemente para crear un webservice proxy client a través de una librería externa con wsimport que pondré próximamente en un post.

Buen código JDE Friends!