Configuración de TIBCO BW Hashicorp Vault: Más Potente y Mejor Protegida en 3 Pasos

Configuración de TIBCO BW Hashicorp Vault: Más Potente y Mejor Protegida en 3 Pasos

Introducción

Este artículo tiene como objetivo mostrar la Configuración de TIBCO BW Hashicorp Vault para integrar su aplicación TIBCO BW con los secretos almacenados en Hashicorp Vault, principalmente para la externalización y gestión de recursos de contraseñas y credenciales.

Como probablemente sepa, en la aplicación TIBCO BW, la configuración se almacena en Propiedades a diferentes niveles (propiedades de Módulo o Aplicación). Puede leer más sobre ellas aquí. Y el propósito principal de esas propiedades es proporcionar flexibilidad a la configuración de la aplicación.

Estas propiedades pueden ser de diferentes tipos, como String, Integer, Long, Double, Boolean y DateTime, entre otros recursos técnicos dentro de TIBCO BW, como se muestra en la imagen a continuación:

Configuración de TIBCO BW Hashicorp Vault: Tipos de Propiedades BW

La integración de TIBCO BW Hashicorp Vault afectará solo a aquellas propiedades de tipo Contraseña (al menos hasta la versión 2.7.2/6.8.1 de BW). La razón detrás de esto es que esas propiedades son el tipo de datos relevantes para la información que es sensible y necesita ser segura. Otros conceptos pueden ser gestionados a través de componentes estándar de Kubernetes como ConfigMaps.

Definición de la Aplicación BW

Vamos a comenzar con una aplicación sencilla, como puede ver en la imagen a continuación:

Configuración de TIBCO BW Hashicorp Vault: Ejemplo de Propiedad

Solo un temporizador simple que se ejecutará una vez e insertará la hora actual en la base de datos PostgreSQL. Usaremos Hashicorp Vault para almacenar la contraseña del usuario de la base de datos para poder conectarnos a ella. El nombre de usuario y la cadena de conexión residirán en un ConfigMap.

Omitiremos la parte de la configuración relacionada con el despliegue de los Contenedores de la aplicación TIBCO BW y enlazaremos a un ConfigMap. Tiene un artículo que cubre eso en detalle en caso de que necesite seguirlo, y nos centraremos solo en el tema relacionado con la integración de TIBCO BW Hashicorp Vault.

Así que necesitaremos decirle a TIBCO BW que la contraseña del Recurso Compartido JDBC estará vinculada a la configuración de Hashicorp Vault, y para hacer eso, lo primero es haber vinculado la Contraseña de los Recursos Compartidos a una Propiedad de Módulo como se muestra en la imagen a continuación:

Configuración de TIBCO BW Hashicorp Vault: Contraseña vinculada a Propiedad de Módulo

Ahora, necesitamos decirle a esta Propiedad de Módulo que está vinculada a Hashicorp Vault, y lo haremos en la Vista de Propiedades de la Aplicación, seleccionando que esta propiedad está vinculada a una Solución de Gestión de Credenciales como se muestra en la imagen a continuación:

Configuración de TIBCO BW Hashicorp Vault: Configuración de Gestión de Credenciales para Propiedad

Y es ahora cuando establecemos la relación de TIBCO BW Hashicorp Vault. Necesitamos hacer clic directamente en el signo más verde, y tendremos una ventana modal que nos pedirá la tecnología de gestión de credenciales que vamos a usar y los datos necesarios para cada una de ellas, como puede ver en la siguiente imagen:

Configuración de TIBCO BW Hashicorp Vault: Configuración de Gestión de Credenciales para Propiedad

Seleccionaremos Hashicorp Vault como el proveedor. Luego necesitaremos proporcionar tres atributos que ya comentamos en el artículo anterior cuando comenzamos a crear secretos en Hashicorp Vault:

  • Nombre del Secreto: este es el nombre del secreto después de la ruta raíz del elemento.
  • Clave del Secreto: Esta es la clave dentro del propio secreto
  • Ruta de Montaje: Esta es la ruta raíz del secreto

Para obtener más detalles sobre estos tres conceptos, por favor, consulte nuestro artículo sobre cómo crear secretos en Hashicorp Vault.

Así que con todo esto, tenemos prácticamente todo lo que necesitamos para conectarnos a Hashicorp Vault y obtener el secreto, y desde el lado de TIBCO BW BusinessStudio, todo está hecho; podemos generar el archivo EAR y desplegarlo en Kubernetes porque aquí está la última parte de nuestra configuración.

 Despliegue en Kubernetes

Hasta este momento, ya hemos proporcionado la siguiente información:

  • Proceso BW que tiene el inicio de sesión para conectarse a la Base de Datos e insertar información
  • Enlace entre la propiedad de contraseña utilizada para conectar y la definición del Secreto de Hashicorp

Así que, prácticamente todo está ahí, pero falta un concepto. ¿Cómo se conectará el Pod de Kubernetes a Hashicorp una vez que el pod esté desplegado? Hasta este punto, no proporcionamos la ubicación del servidor de Hashicorp Vault del método de autenticación para conectarse a él. Esta es la parte que falta de la integración de TIBCO BW Hashicorp Vault y será parte del archivo YAML de Despliegue de Kubernetes.

Lo haremos usando las siguientes propiedades de entorno en este ejemplo:

Configuración de TIBCO BW Hashicorp Vault: Variables de Entorno de Hashicorp
  • HASHICORP_VAULT_ADDR: Esta variable apuntará a donde se encuentra el servidor de Hashicorp Vault
  • HASHICORP_VAULT_AUTH: Esta variable indicará qué opciones de autenticación se utilizarán. En nuestro caso, usaremos la de token como usamos en el artículo anterior
  • HASHICORP_VAULT_KV_VERSION: Esta variable indica qué versión de la solución de almacenamiento KV estamos usando y será dos por defecto.
  • HASHICORP_VAULT_TOKEN: Este será solo el valor del token para poder autenticarse contra el servidor de Hashicorp Vault

Si está utilizando otros métodos de autenticación o simplemente quiere saber más sobre esas propiedades, por favor, eche un vistazo a esta documentación de TIBCO.

Con todo eso agregado a las propiedades de entorno de nuestra aplicación TIBCO BW, podemos ejecutarla, y obtendremos una salida similar a esta, que muestra que la integración de TIBCO BW Hashicorp Vault se ha realizado y la aplicación pudo iniciarse sin ningún problema

Configuración de TIBCO BW Hashicorp Vault: Ejecución de ejemplo

Módulos TIBCO BW: 3 cosas que necesitas saber para tener éxito

Módulos TIBCO BW: 3 cosas que necesitas saber para tener éxito

Los módulos de TIBCO BW son uno de los contenidos más relevantes en tus desarrollos de TIBCO BW. Aprende todos los detalles sobre los diferentes módulos de TIBCO BW disponibles y cuándo usar cada uno de ellos.

TIBCO BW ha evolucionado de varias maneras y se ha adaptado a los últimos cambios de arquitectura. Debido a eso, desde la concepción de la última versión principal, ha introducido varios conceptos que es importante dominar para poder desatar todo el poder que esta notable herramienta te proporciona. Hoy vamos a hablar sobre los módulos.

Cada aplicación de TIBCO BW está compuesta por diferentes módulos que son los componentes que alojan toda la lógica que puedes crear, y eso es lo primero que hay que anotar: Todo tu código y todo lo que haces en tu aplicación pertenecerá a un módulo de TIBCO BW.

Si pensamos en la jerarquía normal de los componentes de TIBCO BW, será algo como la imagen a continuación:

Módulos TIBCO BW: 3 cosas que necesitas saber para tener éxito

En el nivel superior, tendremos la aplicación; en el segundo nivel, tendremos los módulos, y después de eso, tendremos los paquetes y finalmente, los componentes técnicos como Procesos, Recursos, Clases, Esquemas, Interfaces, etc. Aprende más sobre esto aquí.

Clasificación de Módulos de TIBCO BW

Hay varios tipos de módulos y cada uno de ellos proporciona un caso de uso específico y tiene algunas características asociadas con él.

  • Módulo de Aplicación: Es el tipo de módulo más importante porque sin él no puedes tener una aplicación. Es el módulo maestro y solo puede haber uno por aplicación. Es donde residirá toda tu lógica principal para esa aplicación.
  • Módulo Compartido: Es el otro único módulo nativo de BW y su propósito principal, como muestra el nombre, es alojar todo el código y componentes que pueden ser compartidos entre varias aplicaciones. Si tienes experiencia con versiones anteriores de TIBCO BW, puedes pensar en este módulo de TIBCO BW como un reemplazo de una Biblioteca de Tiempo de Diseño (también conocida como DTL) o si tienes experiencia con un lenguaje de programación, una biblioteca que se importa al código. Debido a eso, no tiene una restricción en el número de aplicaciones que pueden usar un módulo compartido y no hay limitación en el número de módulos compartidos que una aplicación de TIBCO BW puede tener.
  • Módulo OSGI: Este módulo es el que no es nativo de BW y no va a incluir objetos de BW como Procesos, Recursos, etc., y están principalmente concebidos para tener clases Java. Y nuevamente, es más como un módulo auxiliar que también puede ser compartido según sea necesario. Los escenarios habituales para usar este tipo de módulo son definir funciones XPath personalizadas, por ejemplo, o tener código Java compartido entre varias aplicaciones.

Tanto los módulos compartidos como los módulos OSGI pueden definirse como dependencias de Maven y usar el proceso de Maven para publicarlos en un repositorio de Maven y también para ser recuperados de él según la declaración.

Eso proporciona una forma muy eficiente para la distribución y control de versiones de estos componentes compartidos y, al mismo tiempo, ofrece un proceso similar para otros lenguajes de programación como Java, de modo que disminuirá la curva de aprendizaje para ese proceso.

Limitaciones de los Módulos de TIBCO BW

Como ya comentamos, hay algunas limitaciones o características especiales que cada módulo tiene. Debemos ser muy conscientes de ello para ayudarnos a distribuir adecuadamente nuestro código utilizando el tipo correcto de módulos.

Como se comentó, una aplicación solo puede tener un módulo de aplicación de TIBCO BW. Aunque técnicamente es posible tener el mismo módulo de aplicación de BW en más de una aplicación, eso no tiene sentido porque ambas aplicaciones serán las mismas ya que su código principal será el mismo.

Los módulos compartidos de TIBCO BW, por otro lado, no pueden tener componentes de inicio o procesos de activación como parte de su declaración y todos ellos deben residir en el módulo de aplicación de TIBCO BW.

Tanto el módulo de aplicación de TIBCO BW como el módulo compartido de TIBCO BW pueden tener código Java, pero por otro lado, el módulo OSGI puede solo tener código Java y ningún otro recurso de TIBCO BW.

Los módulos compartidos de TIBCO BW pueden exportarse de dos maneras diferentes, como módulos regulares (archivo ZIP con el código fuente) y en formato binario, para ser compartidos entre otros desarrolladores pero no permitiéndoles cambiar o cambiar su vista de los detalles de implementación. Esto todavía se admite por razones de legado, pero la forma recomendada hoy en día para distribuir el software es usando Maven, como se discutió anteriormente.

Casos de Uso de los Módulos de TIBCO BW

Como se comentó, hay diferentes casos de uso para cada uno de los módulos que debido a eso te ayudará a decidir qué componente funciona mejor para cada escenario:

  • Los módulos compartidos de TIBCO BW cubren todos los componentes estándar necesarios para todas las aplicaciones. Aquí, el caso de uso principal son los componentes del marco o patrones principales que simplifican el desarrollo y homogeneizan. Esto ayuda a controlar capacidades estándar como manejo de errores, auditoría, registro, o incluso comunicación interna, por lo que los desarrolladores solo necesitan centrarse en la lógica de negocio para su caso de uso.
  • Otro caso de uso para el módulo compartido de TIBCO BW encapsula cualquier cosa compartida entre aplicaciones, como recursos, para conectarse a un backend, por lo que todas las aplicaciones que necesitan conectarse a ese backend pueden importar y evitar la necesidad de rehacer esa parte.
  • El módulo OSGi es para tener código Java que tiene una relación débil con el código BW, como un componente para realizar una actividad como firmar un documento PDF o integrar con un elemento usando una API nativa de Java para que podamos mantenerlo y evolucionarlo separado del código de TIBCO BW.
  • Otro caso para el módulo OSGI es definir las funciones XPath personalizadas que necesitarás como parte de tu módulo compartido o tu módulo de aplicación.
  • El módulo de aplicación de TIBCO BW, por otro lado, solo debe tener código que sea específico para el problema de negocio que estamos resolviendo aquí, moviendo todo el código que pueda ser utilizado para más de una aplicación a un módulo compartido.

Aprende ahora 2 maneras de configurar la reconexión de TIBCO BW EMS

Aprende ahora 2 maneras de configurar la reconexión de TIBCO BW EMS

En este artículo vamos a cubrir cómo funciona la reconexión de TIBCO BW EMS y cómo puedes aplicarla en tu aplicación, así como los pros y contras de las diferentes opciones disponibles.

Uno de los principales problemas que todos hemos enfrentado al trabajar en una integración de TIBCO BW y EMS es la parte de la reconexión. Aunque esto es algo que necesitamos en ocasiones mínimas debido a la extrema fiabilidad del servidor TIBCO EMS, puede tener consecuencias graves si no lo tenemos bien configurado.

Pero antes de empezar a hablar sobre las opciones, necesitamos hacer una pequeña explicación de fondo para entender completamente la situación.

Normalmente, hay dos formas que podemos usar para conectar nuestra aplicación TIBCO BW a nuestro servidor TIBCO EMS: Directa y JNDI. Y basado en eso, esto cambiará cómo y dónde necesitamos configurar nuestras propiedades de reconexión.

TIBCO BW + EMS: Conexión Directa

Esto es, como suena, una conexión directa de la aplicación TIBCO BW al servidor EMS en sí, con el listener usado para enviar y recibir mensajes. No hay un componente en el medio, y puedes detectarlo porque en los Recursos de Conexión JMS, se mostrará como “Directo”, y la URL siempre será de la siguiente manera: tcp://servidor: puerto como puedes ver en la imagen a continuación:

Aprende ahora 2 maneras de configurar la reconexión de TIBCO BW EMS
TIBCO BW + EMS: Conexión Directa

 TIBCO BW + EMS: Conexión JNDI

Esta es un tipo de conexión diferente, y tiene un componente central comparado con el enlace Directo, como puedes imaginar. En este escenario, en el momento de la conexión, la aplicación TIBCO BW realiza una primera conexión al servidor JNDI que está dentro del servidor TIBCO EMS y busca los detalles de la conexión basándose en una “Fábrica de Conexiones”. Esta fábrica de conexiones tendrá su URL de conexión y propiedades de conexión. La aplicación TIBCO BW recibirá esa información y comenzará a conectarse a ese servidor EMS.

Sabrás que estás usando una Conexión JNDI porque el Tipo de Fábrica de Conexiones ahora mostrará JNDI. Además, requerirás un nombre de recurso adicional, recurso JNDI, y tu URL de conexión será algo como esto tibjmsnaming://servidor:puerto.

Aprende ahora 2 maneras de configurar la reconexión de TIBCO BW EMS
Aprende ahora 2 maneras de configurar la reconexión de TIBCO BW EMS
 TIBCO BW + EMS: Conexión JNDI

Propiedades de Reconexión de TIBCO EMS

Diferentes propiedades gestionan el proceso de reconexión. Esas propiedades afectarán el comportamiento de la biblioteca cliente EMS que reside en la aplicación cliente, en este caso, la aplicación TIBCO BW. Las propiedades controlarán los siguientes aspectos: el número de intentos de conexión, intervalos de tiempo entre ellos y el tiempo de espera del intervalo para considerarlo un intento fallido.


Y tendrás cada una de estas propiedades para el proceso de reconexión y el proceso de conexión. La principal diferencia es que el proceso de conexión solo actuará cuando estés estableciendo una conexión por primera vez (al inicio de la aplicación TIBCO BW). Las configuraciones de reconexión se aplicarán cuando pierdas una conexión previamente establecida.

Las propiedades concretas son las siguientes:

  • tibco.tibjms.reconnect.attemptcount/tibco.tibjms.connect.attemptcount: Definirá el número de intentos que realizarás cuando se detecte un escenario de reconexión.
  • tibco.tibjms.reconnect.attemptdelay/tibco.tibjms.connect.attemptdelay: Definirá el intervalo de tiempo entre dos intentos de reconexión.
  • tibco.tibjms.reconnect.attempts/tibco.tibjms.connect.attempts: Servirá como una combinación de attemptcount y attemptdelay en una versión separada por comas.
  • tibco.tibjms.reconnect.attempt.timeout/tibco.tibjms.connect.attempt.timeout: Definirá el tiempo de espera para cada uno de los intentos de reconexión, y si se alcanza ese tiempo, la reconexión no se establece; se detectará como un intento fallido.

 ¿Dónde Configurar las Propiedades de Reconexión?

En el caso de que estemos hablando de una conexión Directa, estas propiedades deben especificarse en la aplicación TIBCO BW, y estas propiedades se establecerán como propiedades JVM.

Por lo tanto, dependiendo de tu modelo de implementación, estas propiedades deberán agregarse al archivo AppNode TRA o a las variables de entorno BW_JAVA_OPS si estamos hablando de una implementación en contenedores.

Por otro lado, si hablamos de una conexión JNDI, estas propiedades se establecerán a nivel de EMS como parte de las propiedades de reconexión de la Fábrica de Conexiones. Esto se puede hacer usando el componente CLI tibemsadmin, poniéndolo directamente en el archivo factories.conf, o incluso usando una herramienta gráfica como gEMS usando la sección de Fábricas para actualizar eso, como se muestra en la imagen a continuación:

Aprende ahora 2 maneras de configurar la reconexión de TIBCO BW EMS

Dependiendo del enfoque que sigas, las propiedades se aplicarán en tiempo de ejecución (enfoque gEMS o tibemsadmin) o en el próximo reinicio (factories.conf)

Pros y Contras

Hay diferentes pros y contras al usar un modo de conexión. Basado en las propiedades de reconexión, usar una forma centralizada como el modelo JNDI asegura que todos los componentes que usan esa conexión tendrán las mismas propiedades de reconexión. Si necesitas cambiarlo, no necesitas cambiar todas tus aplicaciones TIBCO BW. Eso puede ser un número de hasta cientos.

Pero, al mismo tiempo, el uso de una forma centralizada proporciona menos flexibilidad que la conexión directa donde puedes decidir los valores específicos para cada aplicación o incluso cuáles necesitan configuración de reconexión y cuáles no.

Supongamos que estás buscando simplicidad y facilidad de gestión. En ese caso, siempre optaré por la conexión basada en JNDI porque proporciona más beneficios en esos aspectos, y la falta de flexibilidad generalmente no se requiere en absoluto.

Integración de TIBCO BW y EMS

Integración de TIBCO BW y EMS

TIBCO BW admite muchos métodos de integración diferentes y cientos de conectores que te permiten conectarte a cualquier fuente posible. Pero la verdad debe ser dicha, EMS es uno de los conectores estándar que necesitas habilitar. Es por eso que TIBCO BW y EMS generalmente van juntos cuando se trata de una Plataforma de Integración adecuada.

El soporte JMS para TIBCO BW está listo para usar, pero como cualquier otra implementación de JMS, necesitas proporcionar las bibliotecas del cliente para establecer una conexión real.

Para hacer eso, desde TIBCO BW 6, se proporciona una forma sencilla para simplificar ese proceso, y esto es lo que vamos a cubrir en este artículo.

Descripción del problema

Lo primero es saber que necesitas hacer algo y lo más importante es aprender a entender qué tipo de error está relacionado con este problema. Podrías encontrar dos errores diferentes dependiendo de dónde estés probando esto: en tiempo de diseño o en tiempo de ejecución.

Si estamos hablando de un problema en tiempo de ejecución, puedes ver un rastro similar a este:

2022-06-02T13:27:15,867 ERROR [pool-13-thread-2] c.t.b.thor.runtime.model.Constituent - Se ha producido el siguiente error para "nombre: test-app versión: 1.0.0.qualifier nombre del paquete: test-app " que necesita ser resuelto.
2022-06-02T13:27:15,878 ERROR [pool-13-thread-2] c.t.b.thor.runtime.model.Constituent - TIBCO-BW-FRWK-600053: No se pudo inicializar el Componente BW [ComponentStarter].
<CausedBy> com.tibco.bw.core.runtime.api.BWEngineException: TIBCO-BW-CORE-500232: No se pudo inicializar el Componente BW [ComponentStarter], Aplicación [test-app:1.0] debido a un error de inicialización de actividad.
<CausedBy> com.tibco.bw.core.runtime.ActivityInitException: TIBCO-BW-CORE-500408: No se pudo inicializar la actividad ProcessStarter [JMSReceiveMessage] en el proceso [com.test.Starter], módulo [test-app] **debido a un error inesperado en el ciclo de vida de la actividad.**
**<CausedBy> java.lang.NullPointerException**

Cada vez que veas un java.lang.NullPointerException relacionado con una actividad de Recepción JMS, puedes estar seguro de que el problema está relacionado con la instalación de los controladores.

Si estamos hablando de tiempo de diseño, verás el mismo error cuando intentes iniciar una sesión de Ejecución o Depuración, pero adicionalmente verás el siguiente error cuando estés probando un Recurso de Conexión JMS, como puedes ver en la imagen a continuación:

Integración de TIBCO BW y EMS

Proceso de instalación

El proceso de instalación es bastante simple, pero necesitas acceso a una instalación de EMS o al menos una ubicación en disco con los clientes almacenados. Si ya tienes eso, solo necesitas ir a la siguiente ubicación:

 TIBCO_HOME/bw/<version>/bin

Donde TIBCO_HOME es la carpeta de instalación para la aplicación BusinessWorks, y version es el formato de versión menor (como 6.7, 2.7, 6.8, etc.).

En esta ubicación, ejecutarás el siguiente comando:

 ./bwinstall ems-driver

Esto comenzará y pedirá la ubicación de las bibliotecas del cliente, como puedes ver en la imagen a continuación:

Integración de TIBCO BW y EMS

Y después de eso, realizará el proceso de instalación y terminará con la salida BUILD SUCCESSFULL. Y después de ese punto, necesitarás reiniciar el Business Studio o los componentes de tiempo de ejecución (como AppNodes o bwagent) para que la configuración se aplique.

Solución para la transformación fallida de entrada XSLT en BusinessWorks

Solución para la transformación fallida de entrada XSLT en BusinessWorks

Resolviendo uno de los problemas más comunes de los desarrolladores usando BusinessWorks

El Transformation failed for XSLT input es uno de los mensajes de error más comunes que podrías ver al desarrollar usando las herramientas de TIBCO BusinessWorks. Entender lo que el mensaje está diciendo es esencial para proporcionar una solución rápida.

He visto desarrolladores necesitando horas y horas tratando de solucionar este tipo de error cuando la mayoría de las veces, toda la información que estás recibiendo está justo frente a ti, pero necesitas entender por qué el motor lo está pidiendo.

Pero primero proporcionemos un poco de contexto. ¿De qué error estamos hablando? Estoy hablando de algo como lo que puedes ver en el registro de trazas a continuación:

...
com.tibco.pvm.dataexch.xml.util.exceptions.PmxException: PVM-XML-106027: Transformation failed for XSLT input '<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tns1="http://www.tibco.com/pe/WriteToLogActivitySchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tib="http://www.tibco.com/bw/xslt/custom-functions" version="2.0"><xsl:param name="Mapper2"/><xsl:template name="Log-input" match="/"><tns1:ActivityInput><message><xsl:value-of select="tib:add-to-dateTime($Mapper2/primitive,0,0,1,0,0,0)"/></message></tns1:ActivityInput></xsl:template></xsl:stylesheet>'
	at com.tibco.pvm.infra.dataexch.xml.genxdm.expr.IpmxGenxXsltExprImpl.eval(IpmxGenxXsltExprImpl.java:65)
	at com.tibco.bx.core.behaviors.BxExpressionHelper.evalAsSubject(BxExpressionHelper.java:107)
...

¿Te suena más familiar ahora? Como ya dije, todos los desarrolladores de TIBCO BusinessWorks se han enfrentado a eso. Como dije, he visto a algunos de ellos luchando o incluso rehaciendo el trabajo repetidamente sin encontrar una solución adecuada. Pero la idea aquí es tratar de resolverlo de manera eficiente y rápida.

Comenzaré con las advertencias iniciales: Evitemos re-codificar, rehacer algo que debería funcionar pero no está funcionando, porque no estás ganando en ningún escenario:

  • Si lo rehaces y no funcionó, pierdes x2 tiempo creando algo que ya tienes, y aún estás atascado.
  • Si lo rehaces y funciona, no sabes qué estaba mal, por lo que te enfrentarás a ello nuevamente en breve.

Entonces, ¿cómo funciona esto? Usemos este proceso:

Recopilar —> Analizar —> Entender —> Corregir.

Escenario

Primero, necesitamos recopilar datos, y la mayoría de las veces, como dije, es suficiente con el registro de trazas que tenemos, pero en algún momento, podrías necesitar requerir el código de tu proceso para detectar el error y la solución.

Así que comenzaremos con este código fuente que puedes ver en la captura de pantalla a continuación y la siguiente explicación:

Solución para la transformación fallida de entrada XSLT en BusinessWorks

Tenemos un Mapper que está definiendo un esquema con un elemento int que es una opción, y no estamos proporcionando ningún valor:

Solución para la transformación fallida de entrada XSLT en BusinessWorks

Y luego estamos usando la fecha para imprimir un registro, agregando un día más a esa fecha:

Solución para la transformación fallida de entrada XSLT en BusinessWorks

Solución

Primero, necesitamos entender el mensaje de error. Cuando recibimos un mensaje de error titulado `Transformation failed for XSLT input que dice precisamente esto:

Intenté ejecutar el XSLT que está relacionado con una actividad, y fallé debido a un error técnico

Como probablemente ya sabes, cada una de las actividades de BusinessWorks ejecuta una Transformación XSL internamente para hacer el mapeo de entrada; puedes verlo directamente en el Business Studio. Entonces, este error te está diciendo que este XSL interno está fallando.

Solución para la transformación fallida de entrada XSLT en BusinessWorks

Y la razón es un problema de tiempo de ejecución que no puede ser detectado en tiempo de diseño. Así que, para dejarlo claro, los valores de algunas de tus variables y la transformación fallan. Así que primero, deberías enfocarte en esto. Usualmente, toda la información está en el registro de trazas en sí, así que comencemos a analizar eso:

Solución para la transformación fallida de entrada XSLT en BusinessWorks

Entonces, veamos toda la información que tenemos aquí:

  • En primer lugar, podemos detectar qué actividad está fallando. Puedes hacerlo fácilmente si estás depurando localmente, pero si esto está sucediendo en el servidor puede ser más complicado; pero con esta información, tienes: Todo el XSLT en sí que está impreso en el registro de trazas, por lo que puedes fácilmente
  • También tienes un Causado por que te está diciendo por qué está fallando:
    • Puedes tener varias oraciones de Causado por que deben leerse en modo de cascada, por lo que la más baja es el problema raíz que genera el error para todos los demás arriba, así que deberíamos localizar eso primero.
Solución para la transformación fallida de entrada XSLT en BusinessWorks

En este caso, el mensaje es bastante evidente, como puedes ver en la traza a continuación.

 com.tibco.xml.cxf.runtime.exceptions.FunctionException: XPath function {http://www.tibco.com/bw/xslt/custom-functions}add-to-dateTime exception: gregorian cannot be null.

Así que la función add-to-dateTime falla porque un argumento Gregoriano (es decir, una fecha) es nulo. Y eso es precisamente lo que está sucediendo en mi caso. Si proporciono un valor al parámetro… Voilà, ¡está funcionando!

Solución para la transformación fallida de entrada XSLT en BusinessWorks

 Resumen

Situaciones similares pueden ocurrir con diferentes causas raíz, pero las más comunes son:

  • Problema con elementos opcionales y no opcionales, por lo que un nulo llega a un punto donde debería.
  • Errores de validación porque el parámetro de entrada no coincide con la definición del campo.
  • Tipos XML extendidos que no son compatibles con la función utilizada.

¡Todos estos problemas pueden ser fácilmente y rápidamente resueltos siguiendo el razonamiento que explicamos en este post!

Así que, pongámoslo en práctica la próxima vez que veas a un colega con ese problema y ayúdalo a tener una experiencia de programación más eficiente!

TIBFAQS: Mejorando el Tiempo de Respuesta de tu API SOAP de TIBCO BW en Grandes Cargas Útiles al Usar Apache Commons

TIBFAQS: Mejorando el Tiempo de Respuesta de tu API SOAP de TIBCO BW en Grandes Cargas Útiles al Usar Apache Commons

Descubre cómo ajustar tus servicios SOAP para que sean eficientes para solicitudes de carga masiva 

TIBFAQS: Mejorando el Tiempo de Respuesta de tu API SOAP de TIBCO BW en Grandes Cargas Útiles al Usar Apache Commons
Foto de Markus Spiske en Unsplash

Todos sabemos que cuando estamos implementando una API, necesitamos diseñar cuidadosamente el tamaño que podemos manejar como el máximo tamaño de solicitud. Por ejemplo, deberías saber que para una solicitud en línea, el límite superior habitual es de 1 MB, todo lo que supere eso deberíamos poder manejarlo de manera diferente (las opciones para manejarlo pueden ser dividir las solicitudes o usar otros protocolos en lugar de HTTP para manejar este tipo de cargas). Pero luego la vida real viene a enfrentarnos allí.

No siempre es posible ceñirse al plan. No siempre somos nosotros los que tomamos esa decisión. Y podemos argumentar todo lo que queramos que esto no es una buena idea y eso está bien, pero al mismo tiempo, necesitamos hacer algo que funcione.

Por defecto, cuando estamos exponiendo un Servicio SOAP en TIBCO BusinessWorks, se basa en bibliotecas de terceros para gestionar la solicitud, analizarla y ayudarnos a acceder al contenido de las solicitudes. Algunas de ellas provienen de la Fundación Apache, y de la que vamos a hablar es Apache Commons.

Cuando estamos enviando una solicitud grande a nuestro servicio SOAP, en mi caso, esta es una solicitud SOAP de 11 MB a mi sistema, y empiezo a ver el siguiente comportamiento:

TIBFAQS: Mejorando el Tiempo de Respuesta de tu API SOAP de TIBCO BW en Grandes Cargas Útiles al Usar Apache Commons
  • El servicio no está respondiendo a mi consumidor.
  • Puedo ver un uso significativo del hilo del Conector HTTP manejando la solicitud antes de enviarla al servicio real.
  • La CPU y la memoria están aumentando mucho.

Entonces, ¿cómo podemos mejorar eso? Lo primero es profundizar más en los detalles sobre ese uso extensivo de la CPU. Por ejemplo, si vamos al seguimiento de pila que los hilos del Conector HTTP están ejecutando, puedes ver el siguiente seguimiento de pila:

TIBFAQS: Mejorando el Tiempo de Respuesta de tu API SOAP de TIBCO BW en Grandes Cargas Útiles al Usar Apache Commons

Puedes obtener esa información de varias fuentes:

  • Una es usar el JVisual VM e ir a los detalles del snapshot en las muestras como lo hice yo.
  • También puedes obtener un volcado de hilos y usar herramientas como https://fastthread.io/index.jsp para visualizarlo gráficamente.

Aquí podemos ver que estamos atascados en el método de registro. Y eso es extraño, ¿por qué estoy registrando estas solicitudes si no estoy haciendo eso en la configuración de BusinessWorks? La respuesta es bastante simple: las bibliotecas de Apache tienen su propio sistema de registro que no se ve afectado por la configuración de logback que usa BusinessWorks.

Entonces, podemos desactivar eso usando la siguiente propiedad JVM:

-Dorg.apache.commons.logging.Log=org.apache.commons.logging.impl.NoOpLog

El tiempo de respuesta ha mejorado de 120 segundos para 11 MB a menos de 3 segundos, incluyendo toda la lógica que el servicio estaba haciendo. Bastante impresionante, ¿verdad?

TIBFAQS: Mejorando el Tiempo de Respuesta de tu API SOAP de TIBCO BW en Grandes Cargas Útiles al Usar Apache Commons

Resumen

Espero que encuentres esto interesante, y si eres uno de los que enfrenta este problema ahora, tienes información para no detenerte por este. Si deseas enviar tus preguntas, no dudes en usar una de las siguientes opciones:

  • Twitter: Puedes enviarme una mención a @alexandrev en Twitter o un DM o incluso solo usando el hashtag #TIBFAQS que monitorearé.
  • Email: Puedes enviarme un correo electrónico a alexandre.vazquez en gmail.com con tu pregunta.
  • Instagram: Puedes enviarme un DM en Instagram a @alexandrev
TIBFAQS: Mejorando el Tiempo de Respuesta de tu API SOAP de TIBCO BW en Grandes Cargas Útiles al Usar Apache Commons

#TIBFAQS Habilitación de la depuración remota para la aplicación TIBCO BusinessWorks en Kubernetes

#TIBFAQS Habilitación de la depuración remota para la aplicación TIBCO BusinessWorks en Kubernetes

Proporcione más agilidad a sus esfuerzos de resolución de problemas depurando exactamente donde ocurre el error utilizando técnicas de Depuración Remota

#TIBFAQS Habilitación de la depuración remota para la aplicación TIBCO BusinessWorks en Kubernetes
Foto de Markus Winkler en Unsplash

La revolución de los contenedores ha proporcionado muchos beneficios, como hemos discutido en profundidad en otros artículos, y al mismo tiempo, también ha proporcionado algunos nuevos desafíos que necesitamos abordar.

Toda la agilidad que ahora tenemos en manos de nuestros desarrolladores también necesita extenderse al trabajo de mantenimiento y solución de problemas. Necesitamos ser ágiles también. Conocemos algunos de los principales problemas que tenemos al respecto: Funciona en mi entorno, con el conjunto de datos que tengo, no pude ver el problema, o no pude reproducir el error, son solo frases que escuchamos una y otra vez y retrasan la resolución de algunos errores o mejoras, incluso cuando la solución es simple, luchamos por obtener un escenario real para probar.

Y aquí es donde entra la Depuración Remota. La Depuración Remota es, tal como su propio nombre indica claramente, poder depurar algo que no es local, que es remoto. Se ha centrado desde su concepción en el Desarrollo Móvil porque no importa cuán bueno sea el simulador. Siempre necesitarás probar en un dispositivo real para asegurarte de que todo funcione correctamente.

Así que este es el mismo concepto pero aplicable a un contenedor, lo que significa que tengo una aplicación TIBCO BusinessWorks ejecutándose en Kubernetes. Queremos depurarla como si estuviera ejecutándose localmente, como se muestra en la imagen anterior. Para poder hacer eso, necesitamos seguir estos pasos:

Habilitar la Depuración Remota en el pod

El primer paso es habilitar la opción de depuración remota en la aplicación y para hacerlo, necesitamos usar la API interna que proporciona BusinessWorks, y para hacerlo, necesitamos ejecutar desde dentro del contenedor:

curl -XPOST http://localhost:8090/bw/bwengine.json/debug/?interface=0.0.0.0&port=5554&engineName=Main

En caso de que no tengamos ninguna herramienta como curl o wget para acceder a una URL dentro del contenedor, siempre puedes usar la estrategia de port-forward para hacer que el puerto 8090 del pod sea accesible para habilitar el puerto de depuración usando un comando similar al siguiente:

kubectl port-forward hello-world-test-78b6f9b4b-25hss 8090:8090

Y luego, podemos acceder desde nuestra máquina local para habilitar la depuración remota

Hacer que el Puerto de Depuración sea accesible para el Studio

Para hacer la depuración remota, necesitamos poder conectar nuestro TIBCO BusinessStudio local a este pod específico que está ejecutando la carga y, para hacerlo, necesitamos tener acceso al puerto de depuración. Para obtener esto, tenemos principalmente dos opciones que son las que se muestran en las subsecciones a continuación: Exponer el puerto a nivel del pod y opción de port-forwarding.

Exponer el puerto a nivel del Pod

Necesitamos tener el puerto de depuración abierto en nuestro pod. Para hacer eso, necesitamos definir otro puerto que no esté en uso por la aplicación, y que no sea el puerto de administración predeterminado (8090) para el que se va a exponer. Por ejemplo, en mi caso, usaré 5554 como el puerto de depuración, y para hacerlo, defino otro puerto para ser accedido.

#TIBFAQS Habilitación de la depuración remota para la aplicación TIBCO BusinessWorks en Kubernetes
Definición del puerto de depuración como un Servicio

Opción de Port-Forwarding

Otra opción si no queremos exponer el puerto de depuración todo el tiempo, incluso si no se va a usar a menos que estemos ejecutando la depuración remota, tenemos otra opción para hacer un port-forward al puerto de depuración en nuestro local.

kubectl port-forward hello-world-test-78b6f9b4b-cctgh 5554:5554

Conexión al TIBCO Business Studio

Ahora que tenemos todo listo, necesitamos conectar nuestro TIBCO Business Studio local al pod, y para hacerlo, necesitamos seguir estos pasos:

Ejecutar → Configuraciones de Depuración, y seleccionamos el BusinessWorks Remoto

#TIBFAQS Habilitación de la depuración remota para la aplicación TIBCO BusinessWorks en Kubernetes
Selección de la opción de aplicación BusinessWorks Remoto en la Configuración de Depuración

Y ahora necesitamos proporcionar los detalles de la conexión. Para este caso, usaremos el localhost y el puerto 5554 y haremos clic en el botón de Depuración.

#TIBFAQS Habilitación de la depuración remota para la aplicación TIBCO BusinessWorks en Kubernetes
Configuración de las propiedades de conexión para la Depuración Remota

Después de ese momento, estableceremos una conexión entre ambos entornos: el pod ejecutándose en nuestro clúster de Kubernetes y nuestro TIBCO BusinessStudio local. Y tan pronto como accedamos al contenedor, podemos ver la ejecución en nuestro entorno local:

#TIBFAQS Habilitación de la depuración remota para la aplicación TIBCO BusinessWorks en Kubernetes
Ejecución de Depuración Remota desde nuestra instancia de TIBCO BusinesStudio

Resumen

Espero que encuentres esto interesante, y si eres uno de los que enfrenta este problema ahora, tienes información para no detenerte por este. Si deseas enviar tus preguntas, no dudes en usar una de las siguientes opciones:

  • Twitter: Puedes enviarme una mención a @alexandrev en Twitter o un DM o incluso solo usando el hashtag #TIBFAQS que monitorearé.
  • Email: Puedes enviarme un correo electrónico a alexandre.vazquez en gmail.com con tu pregunta.
  • Instagram: Puedes enviarme un DM en Instagram a @alexandrev
#TIBFAQS Habilitación de la depuración remota para la aplicación TIBCO BusinessWorks en Kubernetes

#TIBFAQS: Configuración de TIBCO BW en Tiempo de Ejecución

#TIBFAQS: Configuración de TIBCO BW en Tiempo de Ejecución

Descubre cómo el comando OSGI lcfg puede ayudarte a estar seguro de cuál es la configuración en tiempo de ejecución.

#TIBFAQS: Configuración de TIBCO BW en Tiempo de Ejecución
Foto de Ferenc Almasi en Unsplash

Conocer la configuración de TIBCO BW en tiempo de ejecución se ha vuelto crítico ya que siempre necesitas saber si los últimos cambios se han aplicado o simplemente quieres verificar el valor específico de una Propiedad del Módulo como parte de tu desarrollo.

Cuando hablamos de aplicaciones desplegadas en la nube, una de las cosas clave es la Gestión de Configuración. Especialmente si incluimos en la mezcla cosas como Kubernetes, Contenedores, Sistema de Gestión de Configuración Externa, las cosas se complican.

La configuración habitual cuando hablamos de un entorno Kubernetes para la gestión de configuración es el uso de Config Maps o Spring Cloud Config.

Cuando puedes cargar la configuración en un paso separado al de desplegar la aplicación, puedes encontrarte en una situación en la que no estás seguro de cuál es la configuración en ejecución que tiene una aplicación BusinessWorks.

Para verificar la configuración de TIBCO BW hay una manera fácil de saber exactamente los valores actuales:

  • Solo necesitamos entrar en el contenedor para poder acceder a la consola interna de OSGI que nos permite ejecutar comandos administrativos.
  • Hemos hablado otras veces sobre esa API, pero en caso de que quieras echar un vistazo más profundo solo necesitas revisar este enlace:
  • Y uno de los comandos es lcfg que permite saber qué configuración está siendo utilizada por la aplicación que está en ejecución:
curl localhost:8090/bw/framework.json/osgi?command=lcfg

Con una salida similar a esta:

#TIBFAQS: Configuración de TIBCO BW en Tiempo de Ejecución
Salida de ejemplo para el comando lcfg de una Aplicación de Contenedor BusinessWorks en Ejecución

Resumen

Espero que encuentres esto interesante, y si eres uno de los que enfrenta este problema ahora, tienes información para no ser detenido por este. Si deseas enviar tus preguntas, siéntete libre de usar una de las siguientes opciones:

  • Twitter: Puedes enviarme una mención a @alexandrev en Twitter o un DM o incluso solo usando el hashtag #TIBFAQs que monitorearé.
  • Email: Puedes enviarme un correo electrónico a alexandre.vazquez en gmail.com con tu pregunta.
  • Instagram: Puedes enviarme un DM en Instagram a @alexandrev
#TIBFAQS: Configuración de TIBCO BW en Tiempo de Ejecución

#TIBFAQS: Estado Deteriorado de TIBCO BW: ¿Cómo solucionarlo?

#TIBFAQS: Estado Deteriorado de TIBCO BW: ¿Cómo solucionarlo?

Aprende las principales razones detrás de un estado Deteriorado y cómo puedes realizar la resolución de problemas para identificar y resolver el error.

#TIBFAQS: Estado Deteriorado de TIBCO BW: ¿Cómo solucionarlo?
Foto de Charles Deluvio en Unsplash

Este es otro post de la serie #TIBFAQS. Para recordarte de qué se trata todo esto, puedes enviar tus preguntas sobre problemas o dudas de desarrollo de TIBCO e intentar proporcionar una respuesta aquí para tratar de ayudar a la comunidad de desarrolladores de TIBCO.

Así que hoy voy a comenzar con uno de los problemas más comunes cuando trabajamos con BusinessWorks, y es cuando voy a desplegar mi aplicación o probarla localmente, y obtengo este rastro de registro y nada después de eso: Estado Deteriorado de TIBCO BW.

#TIBFAQS: Estado Deteriorado de TIBCO BW: ¿Cómo solucionarlo?
Mensaje de error de estado deteriorado

Esta es una de las situaciones habituales para un desarrollador junior de BusinessWorks y una de las razones por las que pasas más tiempo haciendo resolución de problemas. Vamos a obtener algunos trucos hoy, para que este mensaje nunca más te detenga en tu camino a producción.

¿Cuál es la causa de este error?

Este error significa que el tiempo de ejecución de BusinessWorks no puede cumplir con todas las dependencias entre los componentes para poder iniciar. Como probablemente sepas, en BusinessWorks cada uno de los componentes de las aplicaciones se gestiona de manera independiente y se referencian entre sí.

Por ejemplo, la Aplicación depende del Módulo de Aplicación y el Módulo Compartido. El módulo de Aplicación puede tener una dependencia de una Conexión JMS y así sucesivamente.

Situaciones que pueden provocar este error

Veamos ahora la situación que puede provocar este error y cómo resolverlo.

1.- Módulo faltante o versiones incompatibles

Una situación habitual que puede llevar a este problema es la falta de módulos o versiones incompatibles de los módulos. En ese caso, el componente referenciable esperará un módulo o una versión específica de un módulo para iniciarse. Sin embargo, este módulo falta o está iniciando otra versión.

2.- Conexiones compartidas no válidas

Otra opción puede ser si algunos de los componentes requieren establecer la conexión con otras tecnologías como conexiones JDBC, conexiones JMS, conexiones KAFKA u otro de los más de 200 conectores disponibles.

3.- Componente de Inicio faltante en los Descriptores de Módulo

El último de los sospechosos habituales aquí es cuando tienes un componente de Inicio en los Descriptores de Módulo, pero este proceso no está disponible dentro del archivo EAR que estás desplegando. Esa dependencia nunca se satisface, y eso lleva a un estado Deteriorado ilimitado.

¿Cómo detectar qué componente está faltando?

Para ayudarte en el proceso de detectar en qué situación te encuentras, tienes una herramienta increíble a tu disposición que es el comando la de la Interfaz de Consola OSGi.

Este comando nos ayuda a listar las aplicaciones desplegadas en este AppNode o contenedor específico y nos da los detalles de ellas, incluyendo la razón de una situación Deteriorada.

#TIBFAQS: Estado Deteriorado de TIBCO BW: ¿Cómo solucionarlo?

Cómo ejecutar la consola OSGi depende de tu modelo de despliegue, pero puedes leer toda la información al respecto en el siguiente enlace:

Resumen

Espero que encuentres esto interesante para resolver el estado Deteriorado de TIBCO BW en tus aplicaciones, y si eres uno de los que enfrenta este problema ahora, tienes información para no ser detenido por este. Si deseas enviar tus preguntas, siéntete libre de usar una de las siguientes opciones:

  • Twitter: Puedes enviarme una mención a @alexandrev en Twitter o un DM o incluso solo usar el hashtag #TIBFAQs que monitorearé.
  • Email: Puedes enviarme un correo electrónico a alexandre.vazquez en gmail.com con tu pregunta.
  • Instagram: Puedes enviarme un DM en Instagram a @alexandrev
#TIBFAQS: Estado Deteriorado de TIBCO BW: ¿Cómo solucionarlo?

#TIBFAQS: Error al leer el perfil desde [/tmp/tmp/pcf.substvar]

#TIBFAQS: Error al leer el perfil desde [/tmp/tmp/pcf.substvar]
#TIBFAQS: Error al leer el perfil desde [/tmp/tmp/pcf.substvar]
Foto de Shahadat Rahman en Unsplash

Este es otro post de la serie #TIBFAQS y solo para recordarte de qué se trata todo esto es que puedes enviar tus preguntas sobre problemas o dudas de desarrollo de TIBCO y trato de proporcionar una respuesta aquí para intentar ayudar a la comunidad de desarrolladores de TIBCO allá afuera.

Así que hoy voy a comenzar con uno de los que creo que son los problemas más comunes cuando trabajamos con BusinessWorks Container Edition y estamos desplegando en nuestro entorno objetivo y es un rastro similar a este:

#TIBFAQS: Error al leer el perfil desde [/tmp/tmp/pcf.substvar]
Rastro de error respecto a que no puedo leer el perfil

¿Cuál es la causa de este error?

Este error significa que el runtime de BusinessWorks no puede leer y procesar el archivo de propiedades para iniciar la aplicación. Así que eso significa que tu error está relacionado con la configuración de la aplicación y no con la aplicación en sí. Así que, la buena noticia aquí: tu código parece estar bien en este punto.

Como probablemente sabes, todas las aplicaciones de TIBCO BW usan desde hace mucho tiempo un archivo XML para tener los valores de configuración para comenzar. Este es el archivo que en el caso de BusinessWorks Container Edition se almacena en /tmp/tmp/pcf.substvar y se llena de varias fuentes dependiendo de cómo manejes tu configuración.

Como sabes, tienes varias opciones para manejar tu configuración en entornos basados en la nube: Variables de entorno, Mapas de Configuración, Sistemas de Gestión de Configuración como Spring Cloud Config o Consul… Así que es importante que tengas una comprensión clara de lo que estás usando.

Así que el error es que el archivo tiene algo en su contenido que no es válido, porque está mal o porque no puede entenderlo.

Situaciones que pueden provocar este error

Veamos ahora la situación que puede provocar este error y cómo podemos solucionarlo.

1.- Incompatibilidad entre versiones de BW-runtime y EAR

Normalmente, los archivos EAR son compatibles con diferentes runtimes de BusinessWorks, pero esto es cierto cuando el runtime es más actual que el EAR. Así que quiero decir, si genero mi aplicación con BWCE 2.5.0 puedo ejecutarla con runtime 2.5.0, o 2.5.3 o 2.6.0 sin ningún problema, pero si intento ejecutarla con una versión más antigua como 2.4.2 puedo obtener este error porque el archivo EAR tiene algunas «cosas nuevas» que el runtime no puede entender.

Así que es importante validar que la versión del runtime que estás usando es la esperada y actualizarla si ese no es el caso.

2.- Caracteres especiales de XML que necesitan ser escapados

Esta situación solo es cierta en versiones anteriores a la 2.5.0, pero en caso de que estés ejecutando una versión más antigua, también puedes obtener este error porque el valor de tu propiedad tiene un carácter XML que necesita ser escapado. Caracteres como ‘<’ o ‘&’ son los más utilizados para generar este error. Si estás usando una versión más actualizada no necesitas escaparlos porque se escapan automáticamente.

Así que dependiendo de la versión que estés usando, actualiza el valor de tu propiedad en consecuencia.

Resumen

Espero que encuentres esto interesante y si eres uno de los que enfrenta este problema ahora tienes información para no detenerte por este. Si deseas enviar tus preguntas, siéntete libre de usar una de las siguientes opciones:

  • Twitter: Puedes enviarme una mención a @alexandrev en Twitter o un DM o incluso solo usando el hashtag #TIBFAQs que monitorearé.
  • Email: Puedes enviarme un correo electrónico a alexandre.vazquez en gmail.com con tu pregunta.
  • Instagram: Puedes enviarme un DM en Instagram a @alexandrev
#TIBFAQS: Error al leer el perfil desde [/tmp/tmp/pcf.substvar]
#TIBFAQS: No se pudo leer el perfil de [/tmp/tmp/pcf.substvar]