BLOG

Funciones remotas, driver ODBC y procesos web (I)

Por [N4] Paco Satué el | 5 Comments

Seguimos con la serie de artículos dedicados a mostrar las diferentes posibilidades de extender nuestras aplicaciones. En esta ocasión vamos a explorar algunas funcionalidades interesantes desde el punto de vista del intercambio de datos entre una Instancia de Velneo y una aplicación externa, ya sea de Velneo o de otra plataforma distinta.

Vamos a fijarnos en tres herramientas de Velneo diseñadas específicamente para enlazar aplicaciones: las funciones remotas, el driver ODBC y los procesos web.

Son tres formas de extender Velneo y para ello requieren establecer una conexión entre nuestra aplicación cliente y la fuente remota de datos. Veremos que cada herramienta lo hace de manera diferente y eso determina el contexto donde se pueden usar.

Empezamos revisando las funciones remotas, a las que dedicaremos esta primera parte del artículo. Su implementación es cien por cien nativa y por lo tanto no requieren el uso de tecnologías y componentes externos a Velneo.

Funciones remotas

La función remota es un objeto función que podemos llamar desde otro proyecto instanciado en el mismo o distinto servidor vServer.

Cualquier función del proyecto puede ser una función remota cuando tiene marcada la opción «Ejecutable en remoto» en la propiedad Estilos.

Igual que una función normal, la función remota recibe uno a varios parámetros que guardamos en variables locales y devolverá un resultado mediante el comando Set dato de retorno.

Puedes consultar todas las propiedades de la función remota en la documentación de Velneo.

En el proyecto de datos o aplicación se puede invocar la función remota desde cualquier objeto que admita una Fórmula de Velneo.

Llamada a la función remota

Para las funciones remotas no existe un asistente o desplegable que nos muestra la lista de funciones disponibles. Tendremos que usar una sintaxis especial de la siguiente manera:

rfc: idFuncion(dominioIP, idInstancia, usuario, contraseña, parámetros)

  • rfc: es el acrónimo de remote function call.

Funciona como un prefijo que indica que se trata de una llamada a una función remota.

  • idFuncion: es el identificador único asignado a la función remota.

Este es el único valor de la llamada que debe ser un valor fijo y no podemos cambiar en tiempo de ejecución.

  • dominioIP: URL del servidor remoto indicando que la conexión usará el protocolo VATP o VATPS. Es de la forma vatp(s)://dominioIP:puerto. Si no se indica, el puerto por defecto es el 690.

La llamada a una función remota o rfc solo es posible a través del protocolo nativo VATP, por lo que necesitaremos siempre un componente cliente que sea compatible con este protocolo.

  • idInstancia: es el identificador único que tiene la instancia en el servidor remoto y donde estará definida la función remota.

El valor de idInstancia que introduzcamos en la llamada se convertirá siempre a un valor alfanumérico válido para el identificador en Velneo, es decir, todo en mayúsculas y caracteres no válidos pasan a guión bajo.

El Identificador de la Instancia es la etiqueta alfanumérica que la identifica de forma unívoca en el vServer. Accedemos a ella desde el panel de Instancias de vAdmin pulsando Enter o haciendo doble click en la definición.

  • usuario y contraseña: credenciales de un usuario en el vServer remoto que tenga permisos de acceso a la instancia de datos o aplicación donde está definida la función remota.

El acceso en vServer a una Instancia se determina a nivel de Grupos de usuarios, por lo tanto habrá un Grupo de usuarios con acceso explícito a la instancia que contiene la función remota y al que añadiremos el usuario utilizado en la llamada rfc.

Si queremos evitar que un Grupo de usuarios pueda ejecutar instancias de aplicación será más conveniente definir siempre las funciones remotas en una instancia de datos.

  • parámetros: lista de parámetros para la función remota separados por comas. Las funciones pueden recibir como máximo 10 parámetros.

Los tipos de datos de los parámetros estarán determinados por el tipo de las variables locales de la función remota. Podrán ser de tipo alfabético, numérico, fecha, hora, tiempo y booleano.

Velneo hace la conversión de tipo de manera automática y por eso podemos pasar como parámetros literales alfabéticos que se convertirán a los tipos que corresponda según la variable local en la funcíón remota. Por ejemplo, los siguientes valores literales alfabéticos pueden convertirse correctamente a los 6 tipos de variables aceptados en Velneo.

"Esto es una cadena" -> tipo alfabético
"2345.12" -> tipo numérico
"2020/04/12" -> tipo fecha
"23:47" -> tipo hora
"2020/04/12 23:47" -> tipo tiempo
"1" -> tipo booleano

La llamada rfc siempre es síncrona, el proceso llamador quedará paralizado mientras dura la ejecución de la función remota y continuará cuando reciba el retorno o se produzca un timeout.

Errores VATP con la función remota

Ni el identificador de la función remota ni los parámetros de la llamada rfc pueden ser validados por el Inspector de errores de vDevelop.

Tendremos que esperar a la ejecución de vClient para recibir, en caso de producirse, Errores VATP que se mostrarán en la Barra de estado de vClient.

  • Error vatp No existe el elemento. Función remota: <idFuncion erróneo>.
    La llamada rfc retorna 0. Se produce cuando la función remota no existe. En el panel de vAdmin aparece el mensaje: Comando de Ejecución:Ejecutar función remota → No existe el elemento
  • Error vatp Ok. Función remota: <idFuncion>.
    La llamada rfc retorna 0. Se produce cuando no se puede acceder al servidor remoto por diversas causas.
  • Error vatp Instancia desconocida. Función remota: <idFuncion>.
    La llamada rfc retorna 0. En el panel de vAdmin aparece el mensaje: Comando de Ejecución:Ejecutar función remota → Instancia desconocida.
  • Error vatp Error en usuario y contraseña. Función remota: <idFuncion>.
    La llamada rfc retorna 0. En el panel de vAdmin no aparece mensaje alguno.
  • Error vatp No está autorizado a realizar la operación, compruebe permisos. Función remota: <idFuncion>.
    La llamada rfc retorna 0. Se produce cuando el usuario no tiene acceso a la instancia. En el panel de vAdmin aparece el mensaje: Comando de Ejecución:Ejecutar función remota → No está autorizado a realizar la operación, compruebe permisos.
  • Error vatp Error de socket en conexión TCP. Función remota: <idFuncion>.
    La llamada rfc retorna 0. La ejecución de las llamadas rfc es síncrona, y este error se produce cuando vClient reporta un timeout de conexión debido a que una instrucción de la función remota dura más de 10 minutos y no puede demostrar que sigue viva. La aplicación cliente, después de mostrar el error vatp, seguirá ejecutando el código posterior a la llamada rfc y el enganche de la función remota en el servidor puede que nunca llegue a finalizar.

Desde la aplicación no podemos capturar los mensajes de error VATP y por lo tanto tenemos un feedback bastante ineficaz. Solo nos queda considerar que hay un error de la llamada cuando el valor de retorno es 0.

Retorno de la función remota

Como cualquier función de Velneo las funciones remotas usan el comando Set dato de retorno para retornar un valor al cliente.

Ya hemos visto que en caso de error la llamada rfc devuelve 0, por lo tanto tendremos que considerar el valor 0 como un retorno no válido para la aplicación. Si no existe el comando Set dato de retorno en la función remota la llamada rfc devuelve una cadena vacía.

Igual que ocurre con los parámetros de la función remota el tipo del valor retornado lo determina la variable local que recibe el resultado de la fórmula con la llamada rfc.

Es buena práctica que la variable local que recoge el valor de la llamada rfc sea de tipo alfabético para obtener un literal que pueda representar cualquier tipo de dato devuelto por la función remota.

El conjunto de caracteres soportado es siempre UNICODE, tanto en la transmisión de los parámetros como en la recepción del retorno de la función remota a través del protocolo VATP. Así que no debemos preocuparnos por el uso de caracteres fuera del conjunto Latin1.

Monitorización de la función remota

Desde el panel de Mensajes de vAdmin visualizamos los comandos de ejecución del cliente vClient a través del protocolo VATP.

Hay que tener en cuenta que el comando de ejecución Ejecutar función remota no aparece en el panel de mensajes del servidor remoto cuando se ejecuta correctamente una llamada rfc.

Cuando el servidor remoto recibe una llamada rfc el proceso es el siguiente:

  • Comprueba que los identificadores idFunción e idInstancia existen.
  • Si es así, confirma que el usuario pertenece a un grupo con acceso explícito a la instancia.
  • Si la contraseña es correcta creará un nuevo enganche de tipo vRunner.

En la imagen siguiente del panel de Enganches de vAdmin observamos que el usuario asignado a los 3 enganches remotos está en blanco.

Por lo tanto, el usuario de la llamada rfc solo se usa para permitir o no la ejecución de la función remota, ya que si consultamos la variable de sistema sysUsername dentro de la función remota su valor es Server.

La función remota se ejecuta en el servidor en un hilo separado, por lo que se pueden hacer llamadas simultáneas desde diferentes clientes sin bloqueos entre ellas. Como estamos en tercer plano las variables globales y las tablas en memoria de la instancia de datos se comparten entre los diferentes enganches.

Cuando la función remota transacciona observamos en el panel de Transacciones de vAdmin que las columnas Usuario e Instancia están en blanco. La columna Enganche muestra el Testigo que identifica a cada llamada rfc que veíamos en el panel de Enganches.

En el panel de Mensajes de vAdmin (con verboseLevel = 2) sí disponemos de toda la información para monitorizar las transacciones realizadas por las funciones remotas.

Uso de las funciones remotas con Velneo

El uso de funciones remotas en nuestras aplicaciones Velneo tiene dos grandes ventajas frente a otras herramientas: son objetos nativos de vDevelop y su implementación se realiza totalmente sobre el protocolo VATP, por lo que se integran perfectamente con el esquema de seguridad de vServer.

Lo más habitual es que las funciones remotas se usen para conectar diferentes soluciones de Velneo que no heredan entre sí o están en servidores distintos.

Procesos que consolidan datos con la central, replicación de datos, monitorización, logs, descarga de estilos y recursos CSS, etc … son algunos ejemplos del uso que podemos dar a esta herramienta.

Pero quizás la ventaja más importante de las funciones remotas sea que nos permiten diseñar módulos independientes, sin depender de la herencia de instancias en la aplicación principal. Cualquier modificación en un módulo remoto se puede aplicar reiniciando únicamente la instancia afectada sin tener que expulsar los enganches de la aplicación principal.

Usar funciones remotas desde aplicaciones externas

Seguramente ya te estarás preguntando si es posible hacer llamadas rfc desde una aplicación externa a Velneo. Si esto fuera posible podríamos, por ejemplo, proporcionar acceso a la base de datos de nuestro vServer a una aplicación de análisis de datos y toma de decisiones.

Una llamada rfc solo se puede ejecutar a través del protocolo VATP, por lo tanto, necesitaremos un adaptador entre la aplicación externa y el servidor vServer remoto que traduzca los comandos de ejecución de funciones remotas.

Veamos dos opciones de acceso a nuestras funciones remotas desde la aplicación externa.

Librería vRemoteFunctionV7.dll

Con Velneo vClient se distribuye una librería dll (solo para Windows) llamada vRemoteFunctionV7.dll, que nos permite hacer llamadas rfc desde lenguajes de programación o plataformas que sean capaces de cargar y usar librerías DLL de 32 o 64 bits.

La librería vRemoteFunctionV7.dll dispone de una sola función cuyo nombre es RemoteFuncV7. Esta función retorna siempre un valor de tipo char (convención cdecl) y recibe hasta 13 parámetros también de tipo char.

  • szServer: URL del servidor remoto vatp(s)://dominioIP:puerto
  • szInstancia: identificador de la instancia
  • szIdFuncion: identificador de la función remota
  • szUsuario: usuario con acceso explícito a la instancia
  • szPassword: contraseña del usuario
  • szParam1, szParam2, … szParam8: parámetros de la función remota

La librería vRemoteFunctionV7.dll necesita para su funcionamiento las librerías de Qt que se instalan en la carpeta del componente de ejecución vClient. También debemos tener en cuenta si tenemos que usar la versión de 32 o 64 bits que lo determinará la aplicación cliente.

Hay ejemplos de uso en Velneo 6x y en Phyton. En mi caso, he conseguido hacer llamadas rfc usando el lenguaje de scripts AutoIt3 con la función DllCall(). Sin embargo, en macros de aplicaciones Office la convención del paso de parámetros en el lenguaje VBA es siempre StdCall y no se puede usar CDecl que es la que necesita vRemoteFunctionV7.dll.

En cualquier caso, la limitación a la plataforma windows y sin soporte de UNICODE, y que en pruebas realizadas ha demostrado poca fiabilidad, no podría aconsejar su uso.

Componente vClient sin GUI

El componente vClient tiene un modo de ejecución sin Interfaz Gráfica de Usuario (GUI), por lo que es perfecto para usarlo como ejecutor de llamadas rfc desde aplicaciones externas, sustituyendo a la librería vRemoteFunctionV7.dll.

En Windows, el comando para ejecutar vClient sin GUI sería el siguiente:

%ProgramW6432%/Velneo/vClient.exe vatp://usuario:password@dominio/idInstancia -platform minimal

De esta forma disponemos de una solución multiplataforma que actúa de intermediaria entre la aplicación externa y el servidor remoto.

Lamentablemente vClient no admite el paso de parámetros a la instancia de aplicación y tampoco puede retornar datos. Tendremos que habilitar un mecanismo personalizado para el intercambio de información entre la aplicación externa y vClient.

Para pasar los parámetros de la llamada rfc usaremos el archivo de configuración del sistema operativo (archivos ini en Linux y Mac y registro en Windows).

Para retornar datos guardaremos la información en un archivo de texto con codificación Unicode (UTF-16).

En la imagen siguiente podemos ver los pasos secuenciales de una llamada rfc desde una aplicación externa:

  1. La Aplicación externa guarda los parámetros de la llamada en el archivo de configuración.
  2. La Aplicación externa ejecuta el vClient sin GUI y queda a la espera.
  3. El componente vClient lee el archivo de configuración con los parámetros de la llamada.
  4. El componente vClient ejecuta una llamada rfc a través del protocolo VATP y queda a la espera.
  5. La llamada rfc retorna los datos de la función remota a través del protocolo VATP.
  6. El componente vClient guarda los datos de la función remota en un archivo de texto y finaliza.
  7. La Aplicación externa recupera el control y lee los datos desde el archivo de texto.

Componente vClient sin GUI

Vamos a plantear un diseño del componente vClient sin GUI con las siguientes características:

  • Se compone únicamente de un proyecto de aplicación y del objeto AUTOEXEC.
  • La señal Pre-inicialización ejecuta el Manejador AUTOEXEC.PRE_INI.
  • La VRL del servidor remoto, el identificador de la Instancia y las credenciales están prefijadas y no son conocidas por la aplicación externa.
  • La aplicación externa debe proporcionar el Path del archivo de texto para guardar el retorno de la llamada rfc, el identificador de la Función remota y un string con los parámetros de la función remota separados por comas.
  • El Manejador AUTOEXEC.PRE_INI ejecuta los pasos 3,4,5 y 6 del esquema anterior y finaliza devolviendo el control a la aplicación externa.

Con este diseño disponemos de un componente multiplataforma que gestiona nuestras conexiones remotas desde aplicaciones externas, protegiendo el nombre y credenciales de acceso remoto.

El código siguiente puede servir como plantilla para nuestro componente vClient sin GUI.

Rem Proyecto 0PS__MisRemotas_app - Manejador de evento AUTOEXEC.PRE_INI
Rem ( Lee la configuración y ejecuta la llamada rfc guardando el resultado en un archivo de texto )
Libre
Rem ( CONFIGURACION. Lee en el archivo de configuración del SO )
Configuración del sistema: Leer cadena de texto ( "Velneo", "0PS_APPS", "Parametro1", CPARAMETRO_1 )
If ( isEmpty(CPARAMETRO_1) )
   Rem ( No hay parámetros )
   Set retorno proceso = NO
   Finalizar proceso
Libre
Rem ( La clave de Configuración proporciona 3 valores separados con el caracter CSEP )
Set ( CSEP, "#" )
Set ( CPATH_RESUL,  stringSection(CPARAMETRO_1, CSEP, 0, 0, 0) )
Set ( _CFUNCION,    stringSection(CPARAMETRO_1, CSEP, 1, 0, 0) )
Set ( _CPARAMETROS, stringSection(CPARAMETRO_1, CSEP, 2, 0, 0) )
Libre
Rem ( Datos pre-fijados de la llamada rfc - se pueden tomar de una tabla o archivo)
Set ( _CSERVIDOR,  "vatp://<servidor_remoto>" )
Set ( _CINSTANCIA, "ID_INSTANCIA" )
Set ( _CUSUARIO,   "usuario" )
Set ( _CPASSWORD,  "password" )
Libre
Rem ( LISTA de funciones remotas )
If ( _CFUNCION = "FUN_REM_TEST" )
   Set ( CRESUL, rfc: FUN_REM_TEST(_CSERVIDOR, _CINSTANCIA, _CUSUARIO, _CPASSWORD, _CPARAMETROS) )
Else if ( _CFUNCION = "FUN_REM_TEST_CSV" )
   Set ( CRESUL, rfc: FUN_REM_TEST_CSV(_CSERVIDOR, _CINSTANCIA, _CUSUARIO, _CPASSWORD, _CPARAMETROS) )
Else
   Set ( CRESUL, "##ERROR## - No existe la Función remota " + _CFUNCION )
Libre
Rem ( El 0 se considera ERROR )
If ( CRESUL = "0" )
   Set ( CRESUL, "##ERROR## con la Función " + _CFUNCION )
Libre
Rem ( ARCHIVO DE TEXTO. Guardar como UNICODE (UTF-16)
Fichero: Abrir ( hFiche, CPATH_RESUL, Lectura/escritura (Crea o limpia), LOK, UTF-16 )
   Fichero: Grabar línea ( hFiche, CRESUL, LOK)
Libre
Rem ( Cierra vClient y devuelve el control a la aplicación externa )
Set retorno proceso = NO

Si el dominio VATP no es accesible (Firewall) el programa vClient devuelve un error en forma de mensaje y esto provoca un cierre fatal debido a -platform minimal, por lo tanto no lo usamos. En realidad no es necesario porque el Manejador PRE_INI termina con el comando Set retorno proceso = NO que cierra vClient sin haber cargado el Interface.

Llamada rfc desde la aplicación externa

Como ejemplo de aplicación externa podemos probar con Microsoft Excel y un ejercicio que consista en actualizar una Consulta de Datos definida en la Hoja de cálculo.

Creamos una macro VBA para guardar los parámetros de la llamada rfc en el registro de Windows y ejecutar el componente vClient sin GUI (pasos 1 y 2 del esquema).

Rem Macro Excel VBA ThisWorkbook.obtener_ART
...
Rem Configuración
cParametros = cPathResul & cSep & szIdFuncion & cSep & szParametros
Rem Dirección VATP de la aplicación intermediaria que ejecuta las llamadas rfc
cDominioVATP = "vatp://remoto:remoto@c3.velneo.com:10190/0PS__MisRemotas_iapp"
Rem Path del componente vClient sin GUI
cPathExe = Chr(34) & Environ("ProgramW6432") & "\Velneo\vClient.exe" & Chr(34) & " " & cDominioVATP
Rem Guardamos los parámetros en el Registro de Windows para que los lea vClient de Velneo
Shell "REG ADD HKCU\Software\Velneo\0PS_APPS /v Parametro1 /t REG_SZ /d " & Chr(34) & cParametros & Chr(34) & " /f", vbHide
Rem Ejecuta el componente vClient sin GUI y queda a la espera
RetVal = ShellAndWait(cPathExe, 20000, vbMinimizedNoFocus, IgnoreBreak)
Select Case RetVal
    Case ShellAndWaitResult.Success
        Rem Tendremos un archivo de texto en cPathResul con el retorno de la función remota
        Rem Comprobamos si se ha producido un ERROR
        Dim linea As String
        Open cPathResul For Input As #1
        If Not EOF(1) Then
            Line Input #1, linea
        End If
        Close #1
        If Left(linea, Len("##ERROR##")) = "##ERROR##" Then
            MsgBox linea
        Else
            Rem Actualizar la Consulta Power Query leyendo de nuevo el archivo cPathResul
            ActiveWorkbook.Connections("Consulta - " + cConsulta).Refresh
        End If
    ....
End Select

Si añadimos un Botón para ejecutar la macro tendremos una forma directa de realizar una llamada rfc desde la misma Hoja de cálculo. El resultado de la llamada rfc se guarda en un archivo de disco e inmediatamente se refresca la Consulta de datos de la colección ActiveWorkbook.Connections (paso 7 del esquema).

Conclusiones

El objeto función remota es una de las herramientas que podemos usar para extender nuestras aplicaciones Velneo. Es un objeto nativo que funciona sobre el protocolo VATP y por lo tanto las aplicaciones externas necesitarán un componente intermedio como vClient para intercambiar información sobre este protocolo.

La llamada rfc establece una comunicación pero no proporciona un lenguaje estandarizado para el intercambio de datos y tendremos que diseñar nuestro propio API para que nuestros módulos remotos se entiendan entre sí. En la segunda parte de este artículo revisaremos el driver ODBC de Velneo, que además de conectar la aplicación externa con la base de datos va un paso más allá, proporcionando una forma estandar de consultar dicha base de datos mediante SQL.

Os espero entonces para seguir explorando las diferentes posbilidades de extender Velneo.

Velneo es el entorno ágil para el desarrollo
de aplicaciones empresariales

DESCARGAR VELNEO

5 Responses to "Funciones remotas, driver ODBC y procesos web (I)"
  1. Fascinante publicación, como nos tiene acostumbrado el Sr. Paco.

    Gracias Paco, por tu estimable ayuda, como siempre.

  2. [N4] antonioosorio dice:

    Gracias Paco.

    Como siempre muy instructivo.

    Gran trabajo.

  3. [N3] Juanjo dice:

    Muchas gracias Paco.
    Se agradece el esfuerzo.
    Un saludo,

  4. Un saludo Paco desde Colombia Cali, excelente ilustración, ojalá no demores en orientarnos con ODBC y con mucho anhelo esperando PROCESOS-WEB

    Gracias

  5. [N3] emadrigal dice:

    Mis respetos don Paco Satue, muchas gracias por compartir sus grandes conocimientos y por la gran dedicación que ha mostrado durante mucho tiempo.

    Saludos coordiales

    Eladio Madrigal Azofeifa

Deja un comentario

Esta web utiliza cookies. Si continúa navegando acepta dichas cookies y nuestra política de cookies. Gracias. ACEPTAR

Aviso de cookies