#Ensemble

0 Seguidores · 196 Publicaciones

InterSystems Ensemble es una plataforma de integración completa y fácil de utilizar la cual permite que los usuarios se conecten con personas, procesos y aplicaciones en un tiempo

récord.

Aprende más

Documentación

Artículo Muhammad Waseem · jun 28, 2022 1m read

IRIS Interoperability, antes conocida como Ensemble, viene con muchos adaptadores integrados. No tiene un servicio o un adaptador para recibir correo. He escrito un servicio de correo electrónico para recibir mensajes de correo a través de SMTP que se pueden pasar a la operación de correo electrónico.

Ahora quiero hacer una prueba de carga de una producción que envía mensajes a un servidor de correo externo mediante la operación de correo electrónico. El equipo del servidor de correo no quiere que les envíe miles de mensajes.

0
0 153
Pregunta Yone Moreno · jun 13, 2022

Hola buenos días,

Agradeceríamos si ustedes nos leen y responden:

Disponemos de 2 entornos: INTegracion en HealthConnect 2020 y PREproduccion en Ensemble 2018

¿Que un tipo de dato sea %GlobalCharacterStream influye? en concreto: ¿se generan ficheros .stream en el servidor si subimos clases que hagan uso de %GlobalCharacterStream?

Ojeando la documentación, parece que explica lo siguiente:

Parece que NO sería persistente , parece que "almacena caracteres en nodos de datos globales"

2
0 154
Pregunta Yone Moreno · jun 3, 2022

Buenos días,

Agradeceríamos que nos leyeran y si tuvieran oportunidad, nos respondieran, por favor.

La situación actual es la siguiente:

Disponemos de 2 entornos PREproduccion e INTegracion :

Versión de Ensemble en PREproduccion:

Cache for UNIX (Red Hat Enterprise Linux for x86-64) 2018.1.6 (Build 717U) Thu Feb 24 2022 13:27:54 EST

Versión de la herramienta para convertir XML a ER7 y viceversa, el ITB, en PRE (la obtenemos en el fichero ITB.info.cls):

Parameter VERSION = 2.1;

Versión de Ensemble en INTegracion:

3
0 260
Artículo Pierre-Yves Duquesnoy · mayo 3, 2022 14m read

Encontrar errores en tu código o examinar un comportamiento inesperado es el principal objetivo de la depuración.

Trataré de actualizar las herramientas tradicionales aparte de las ayudas que tienen Studio, VScode, Serenji... Las herramientas básicas que han estado ahí antes de que tu EDI preferido lo utilizara en segundo plano.

0
2 193
Artículo Muhammad Waseem · abr 18, 2022 2m read

Antecedentes

En las versiones de InterSystems IRIS >=2021.2 podemos usar irispython para escribir directamente código python encima de nuestras instancias IRIS. Esto nos permite usar paquetes de python, llamar a métodos, hacer consultas SQL y hacer casi cualquier cosa en Objectscript excepto pythonic.

Por ejemplo, a continuación compruebo si hay un namespace:

#!/usr/irissys/bin/irispython
import iris
# call arbitrary class methods
result = iris.cls('%SYS.Namespace').Exists('USER')
if result == 1:
    print(f"Namespace USER is present")

Pero, ¿qué pasa si mi método en IRIS tiene parámetros especiales como Output y ByRef? ¿Cómo podemos usar los parámetros de Salida en irispython?

Por ejemplo, Ens.Director tiene muchos parámetros de salida en sus métodos, ¿cómo puedo usar estos parámetros en python?

Ens.Director:GetProductionStatus

// Un código auxiliar de método de ejemplo de Ens.Director
ClassMethod GetProductionStatus(Output pProductionName As %String, Output pState As %Integer...

Probando los métodos de variables normales

A primera vista, puedes intentar lo siguiente:

import os
# Establecer el namespace de forma manual
os.environ['IRISNAMESPACE'] = 'DEMONSTRATION'

import iris

# PRUEBA 1 con variables de salida
productionName, productionState = None, None
status = iris.cls('Ens.Director').GetProductionStatus(productionName, productionState) 

print("Success? -- {}".format(productionState != None))

¡Pero ambas pruebas no devolverán las variables de salida! Puedes probar esto por ti mismo en cualquier namespace de Ensemble

Usando iris.ref

La utilidad irispython iris.ref se puede utilizar para capturar las variables Output y ByRef.

  1. Crea un objeto iris.ref()
  2. Llama a tu Método ObjectScript
  3. Utiliza la variable .value para obtener el resultado de ese parámetro
import os
# Establecer el namespace de la manera difícil
os.environ['IRISNAMESPACE'] = 'DEMONSTRATION'

import iris

# PRUEBA 2 con variables de salida
productionName, productionState = iris.ref('productionName'), iris.ref('productionState')
status = iris.cls('Ens.Director').GetProductionStatus(productionName, productionState) 

print("Status: {}".format(status))
# see .value
print("Production: {}".format(productionName.value))
# see .value
print("Production State: {}".format(productionState.value))

image

0
0 192
Pregunta Kurro Lopez · oct 29, 2021

Hola a todos.

Estoy intentando crear una regla de enrutamiento para llamar a un web service según el valor de un parámetro de un mensaje.

Mi primer intento es el siguiente:

Tengo una clase común con toda la información, BuscarHuecoRequest, y comprubea cual es el valor de la propiedad "CodigoProveedor".

La tabla T_PROVEEDOR contiene la lista de códigos de los proveedores, si es F, llama a WSF, si es C, llama WSC, etc... Usando un transformador para convertir los valores para este proveedor.

Lanza un error, porque no la propiedad CodigoProveedor no existe.

He depurado y he visto el siguiente código:

1
0 100
Pregunta Yone Moreno · mar 28, 2022

Buenos días,

Agradeceríamos el apoyo de ustedes:

Desarrollando una integración para realizar un circuito "Query / Retrieve" con estudios de imágenes médicas DICOM, necesitaríamos lo siguiente:

Opciones de invocación del servicio DICOM TCP que se ha publicado para esta integración, alternativas a la opción por linea de comando

En concreto hemos leído: Recibir documento DICOM con un PDF embebido y metadatos

Adaptando el ejemplo, empleamos la línea:

./storescu -b VNAPRE -c ESBPRE@10.136.4.XYZ:19ABC ./embeddedpdf.dcm

Mediante la cual simulamos el envío de un documento DICOM con un PDF

1
0 286
Artículo Nancy Martínez · feb 23, 2022 5m read

Os voy a contar cómo hacer una migración de Ensemble a IRIS para chuparse los dedos, es una receta antigua que me pasó mi abuela pero yo le he puesto algunos detallitos. Aquí os la dejo para que cuando os toque alguna podáis tenerlo paso a paso.

Preparar los Nuevos servidores

Lo primero de todo es instalar y configurar la nueva instancia de IRIS, aqui prestamos especial atención a dimensionar adecuadamente el servidor. Atención a la memoria y al espacio en disco para el sistema, para los journals, para las bases de datos y también para los backups. Tambien tened en cuenta si vais a acceder desde puestos remotos en habilitar los puertos adecuados de los firewalls, normalmente usaremos el 22 si hacemos SSH, el 1972 si usamos el Studio y el puerto 52773 para acceder al portal. Aunque si no os gustan esos puertos podeis poner otros. Ya sabeis que la cocina hay que mantenerla siempre limpia y ordenada!

Instalamos IRIS

Pues nada, instalamos IRIS y luego configuramos Global buffers y Routine buffers. Ya sabeis que eso es más importante y casi lo único a configurar para que la cocción salga en su punto. Otra cosa a tocar es la configuración de journals, para evitar que el principal y el alternativo sean el mismo directorio. Así IRIS se queda más tranquilo y nos evitamos algunos warnings que luego salpica todo y aqui que usar el quitagrasas!. Alguna cosilla más que tocar, eliminar la opción de desactivar cuenta después de 90 días de inactividad, porque a veces se queda mucho tiempo sin acceder y te encuentras que no hay manera de entrar. Y a ver quien abre el horno a 200º !!

Tomar nota de todo

En la cocina hay que apuntar todos los ingredientes y ahora toca hacer el catalogo de Namespaces y producciones del servidor que vamos a migrar, anotamos que producciones están en marcha y cuales no y le echamos un vistazo a cada una. No está de más algún pantallazo de algunos detalles para recordar y tomar notas. Que luego la foto del making-of queda muy chula!

Exportar, exportar

Exportamos las producciones y todas las clases que sean de usuario dentro de un Namespace. Eso lo podemos hacer desde el Studio o incluso desde el portal. Al final la idea es tener un paquete XML con todas las clases necesarias de cada Namespace que despues dejaremos en remojo al menos una noche.

Replicar, replicar

Mientras tenemos las clases en remojo, en el nuevo servidor creamos las bases de datos y atenderemos al recurso que se usa, al directorio donde se crea y al nombre de cada una. Espolvorear con sal marina y un poco de aceite.

Ya es el turno de la creación de los Namespaces, esto es fácil, le ponemos un nombre le asociamos las bases de datos creadas y que no se nos olvide que el check para habilitar la interoperabilidad del namespace esté activado para que podamos importar las producciones sin problema. Lo metemos todo en una olla de tamaño grande. Más cositas, ¿qué tal unas aplicaciones Web? pican un poco pero a veces hay aplicaciones web adicionales, tenedlo en cuenta al revisar las producciones del servidor original.

Esto va a gusto del consumidor. Otros ingredientes que debemos tener en cuenta son:

SQL Gateways

Esto es algo muy común en producciones que acceden a bases de datos externas y usan JDBC. Para ello lo primero a tener en cuenta es que en IRIS la versión mínima soportada de JAVA es la 1.8. Podemos usar OpenJDK, por ejemplo para un sistema Linux RedHat podemos instalar OpenJDK11 con un solo comando:

sudo yum install java-11-openjdk-devel

Y tambien es importante obtener los driver JDBC necesarios y colocarlos en una carpeta adecuada. No olvideis descongelarlos con tiempo.

Ahora nos toca exportar todos los SQL Gateways del servidor original. Esto se puede hacer exportando la tabla %Library.sys_SQLConnection como un fichero de texto tipo CSV desde el portal. Es recomendable usar un carácter separador de campos fácilmente reconocible como el |. Y tomad nota de las columnas porque entre versiones el número de columnas o campos de la clase puede cambiar. Normalmente si hay campos nuevos no son obligatorios o necesarios.

Configuraciones SSL

Otros ingredientes comunes son las configuraciones SSL, sobre todo si se usan comunicaciones seguras mediante HTTPS para servicios REST o SOAP. Para ello lo primero copiar los certificados existentes del servidor original y moverlos al nuevo servidor si es posible en las mismas carpetas, sino recordad que luego tendremos que tocarlos a mano.

Para exportar desde el antiguo servidor usaremos:

%SYS>w ##class(Security.SSLConfigs).Export("YYMMDD_SSLConfigsExport.xml")

Y para importar en el nuevo:

%SYS>w ##class(Security.SSLConfigs).Import("YYMMDD_SSLConfigsExport.xml",.NumImported)

Podemos comprobar cuantos se han importado con la variable que hemos pasado por referencia NumImported.

Credenciales

Estas son un rollo, se pueden hacer al ajillo o salteadas pero no he encontrado como exportarlas y se deben hacer a mano. Así que nos toca preguntar las passwords de cada una de ellas. Si encontrais como automatizar esta tarea ponedlo en los comentarios ;-)

Default Settings

Otro ingrediente que aparece por ahi. Hay que revisar y tenerlos en cuenta porque son útiles y si no lo movemos tendremos un problema. Podemos exportalos mediante:

MYNAMESPACE>w ##class(Ens.Config.DefaultSettings).%Export("YYMMDD_MYNAMESPACE_DefaultSettings.xml")

Ojo que esto debeis hacerlo por cada namespace!!. Podeis Importarlos mediante:

MYNAMESPACE>w ##class(Ens.Config.DefaultSettings).%Import("YYMMDD_MYNAMESPACE_DefaultSettings.xml",.NumImported)

Igualmente con NumImported podemos comprobar cuantos settings se han importado.

Importar las clases y compilar

Esto es fácil, vamos por cada namespace importando el fichero XML que exportamos y cruzamos los dedos para que todo vaya bien. De vez en cuando algo no compila bien y toca corregir algún detalle, lo probamos con una cucharita pequeña y con cuidado de no quemarnos. Luego es útil hacer un $system.OBJ.CompileAll() para que así se compile todas las clases dependientes o las que se quedaron sin compilar. Y quedan deliciosas!

Una vez que tenemos esto lo ideal es probar las producciones de manera individual, pero solo un poco que hay que dejar algo para los comensales. Comprobad que todo funciona como debiera siempre con entornos de prueba y no con la vajilla nueva. Esto es lo más pesado y además tendremos que molestar a más gente para validar que la integración hace lo mismo que antes.

Y para terminar postre

Por ejemplo reproducir busquedas guardadas de mensajes si es que había y sobre todo reproducir las tareas programadas que existiesen en el servidor original. Podemos reducirlas con Pedro Ximenez y quedan bien dulces. Reproducir la configuración de Backups, borrado de journals y purgados de mensajerías. Y si seguis usando el Studio, que para mi gusto repite un montón, no olvidar actualizar instalaciones de las máquinas de desarrollo para que puedan acceder a la nueva instancia.

Pues nada, ya teneis una migración rica rica y con fundamento!!

0
0 190
Artículo Robert Cemper · feb 21, 2022 2m read

Durante las últimas semanas, estuve trabajando en varias cuestiones y problemas relacionadas con el desarrollo de software. Me di cuenta de que con frecuencia el análisis de los problemas consistía en perseguir los problemas solo a nivel superficial, pero sin atacar realmente las razones más profundas del problema y sin seguir las consecuencias. Es como el médico que detiene la hemorragia de una pierna pero no ve que en realidad está rota.

0
0 193
Artículo Laura Blázquez García · feb 11, 2022 4m read

Hasta hace no mucho, todos los entornos con los que trabajábamos eran Ensemble 2017.2. Pero recientemente hemos migrado todos los entornos a la versión 2021.1 de IRIS for Health. Ha sido un camino complicado, pero tras analizarlo detenidamente, encontramos la forma de conseguirlo.

Contamos con un servidor de desarrollo y dos servidores en producción en mirroring, en modo Failover. Tenemos más de 40 Namespaces dando servicio, unos con integraciones HL7, otros con servicios Soap, servicios Rest, procesado de archivos... un poco de todo. Necesitábamos estar seguros de que la migración a IRIS no iba a suponer un problema y sobre todo, evitar a toda costa un corte de servicio. Así que lo primero que teníamos que hacer era establecer un plan.

0
0 225
Artículo Muhammad Waseem · dic 22, 2021 3m read

La interoperabilidad en la asistencia sanitaria es esencial para mejorar la atención a los pacientes, reducir los costes de los proveedores de atención médica y ofrecer una imagen más precisa a los proveedores. Pero con tantos sistemas diferentes, los datos se presentan en diferentes formatos. Se han creado muchos estándares para tratar de resolver este problema, incluyendo HL7v2, HL7v3 y CDA, pero cada una tiene sus limitaciones.

FHIR, o Fast Healthcare Interoperability Resources, es un estándar para el intercambio de datos de salud, que tiene como objetivo resolver estos problemas. Fue desarrollado por Health Level Seven International (HL7), una organización que también desarrolló HL7v2, HL7v3 y CDA.

En este artículo descubriremos cómo crear y validar recursos FHIR usando el esquema FHIR con la ayuda de IntelliSense y la función de autocompletado en VS Code.

Paso 1: Descargar el archivo JSON Schema para Validación de Recursos desde la web oficial de FHIR: https://www.hl7.org/fhir/

Paso 2: Crear una carpeta (en este ejemplo estoy usando la carpeta Patient y el recurso Patient) y copiar el archivo fhir.schema.json extraído, en la misma carpeta. A continuación, abrir la carpeta desde VS Code 

 

Paso 3: Configurar el código VS para reconocer el esquema FHIR modificando el archivo setting.json.
Presionar CTRL+SHIFT+P y escribir en el espacio de trabajo settings.json

 

Paso 4: Crear un nuevo archivo patient.fhir.json, en la misma carpeta.
Pulsar Ctrl+ESPACIO y se obtendrán todos los atributos de los recursos de FHIR a través de IntelliSense

Escribir "resourceType": "Patient" y todos los atributos relacionados con el recurso Patient comenzarán a aparecer en el IntelliSense.

VS Code validará automáticamente la estructura y la sintaxis del recurso.


 

Con la ayuda de IntelliSense y la función de autocompletado hemos creado y validado nuestro recurso para los pacientes.

Paso 5: Publicar el recurso creado en el servidor FHIR de InterSystems usando la API Rest de Postman

Recuperar el recurso de Patient Creado utilizando el método GET

¡Enhorabuena! Hemos creado y validado nuestro recurso Patient, y lo hemos publicado y recuperado correctamente en el Servidor FHIR de InterSystems usando Postman.

De esta manera podemos crear y validar fácilmente cualquier Recurso FHIR.

0
1 916
InterSystems Official Mario Sanchez Macias · dic 17, 2021

13 de diciembre de 2021

InterSystems está investigando el impacto de una vulnerabilidad de seguridad relacionada con Apache Log4j2.

La vulnerabilidad — impactando al menos a Apache Log4j2 (versiones 2.0 a 2.14.1) — fue anunciada recientemente por Apache y ha sido notificada en la Base de Datos de Vulnerabilidad Local de Estados Unidos (NVD) como CVE-2021-44228 con la calificación de gravedad más alta, 10.0.

Por favor, consultad esta página para conocer más detalles sobre la vulnerabilidad y actualizaciones sobre si los productos de InterSystems están afectados.

0
0 172
Artículo Kurro Lopez · dic 15, 2021 6m read

El Programador de Ensemble se utiliza para encender y apagar automáticamente los hosts en determinadas fechas y horas. Podrías usarlo si, por ejemplo, solo quisieras ejecutar un host de negocios de 9:00 a 17:00 todos los días. Por el contrario, si desea activar un evento para que ocurra en un momento específico, por ejemplo, un trabajo que se ejecuta a la 01:00, para agrupar y enviar todas las transacciones del día anterior en un archivo, recomendamos otros métodos como el Administrador de tareas.  

0
0 290
Artículo Ricardo Paiva · dic 10, 2021 4m read

Me gustaría compartir algunas funciones de almacenamiento que también existen en Caché y que son prácticamente desconocidas y en su mayoría no se utilizan. Por supuesto, están disponibles en IRIS y son más relevantes con arquitecturas de almacenamiento extensas y distribuidas.

0
0 183
Artículo Ricardo Paiva · dic 3, 2021 2m read

Si defines una tabla/clase persistente, el compilador de clases genera una definición de almacenamiento adecuada. Otra opción es definir un mapeo SQL para un almacenamiento global que ya existe.  Esto ya se explicó estupendamente en otra serie de artículos:  El arte del mapeo de globales para Clases 1 de 3

Después de definir el diagrama de almacenamiento, el compilador de la clase lo podrá ampliar, pero los parámetros fundamentales de almacenamiento no cambiarán.
Esto no significa que no puedas cambiarlo manualmente.

Mi artículo El mapa de bits adoptado incluye un caso como este. Y en combinación con algunas Condiciones WHERE estáticas, como se describió anteriormente, permite que esté disponible también para SQL.

La definición habitual de tus globals de almacenamiento se parecerá a este ejemplo:

<DataLocation>^User.PersonD</DataLocation>
<IdLocation>^User.PersonD</IdLocation>
<IndexLocation>^User.PersonI</IndexLocation>
<StreamLocation>^User.PersonI</StreamLocation
>

Ahora cambiaremos esta definición por una dinámica

<DataLocation>@%MyData</DataLocation>
<IdLocation>@%MyId</IdLocation>
<IndexLocation>@%MyIndex</IndexLocation>
<StreamLocation>@%MyStream</StreamLocation>

y añadimos algo de comodidad

Parameter MANAGEDEXTENT As INTEGER = 0;
ClassMethod SetStorage(ref As %String) As %Integer [ SqlName = SetStorage, SqlProc ]
{
    set %MyData=ref_"D"
      , %MyId=%MyData
      , %MyIndex=ref_"I"
      , %MyStream=ref_"S"
    quit $$$OK
}

Para acceder a los objetos, dirigimos nuestro almacenamiento y lo llenamos

write ##class(Person).SetStorage("^mtemp.Person")
write ##class(Person).Populate(5)

y en SQL:

SELECT  from Person where SetStorage('^mtemp.Person')=1

Funciona con PPG  (^||Person)
mediante el namespace (^|"USER"|Person)
también corresponde al subíndice que se utilizó en El mapa de bits adoptado  con otra variante de ClassMethod SetStorage() 

Para acceso a objetos (sin SQL), funciona incluso para variables locales.
No es el uso deseado, pero demuestra la flexibilidad de esta función. 

Pero ten cuidado. NO funcionará con sharding. Pero eso no es una sorpresa.

0
0 222
Artículo Bernardo Linarez · nov 22, 2021 4m read

Hace algún tiempo, empecé a recibir alertas de consumo excesivo de espacio en el sistema de archivos (filesystem) de un cliente, cuya solución utiliza la capa de interoperabilidad (IRIS / Ensemble) de manera masiva.

Me percaté que las bases de datos que crecían eran las dedicadas a la interoperabilidad, mas no la base de datos operacional de la solución, por tanto había que revisar los mensajes de las diferentes integraciones presentes.

También verifiqué los espacios libres de cada base de datos por si compactar y truncar podrían liberar algún espacio importante, pero no era el caso.

0
1 261
Artículo Bernardo Linarez · nov 22, 2021 3m read

Mas de una vez nos ha sucedido que requerimos añadir algún comportamiento a algún Bussiness Service core (tal como viene "de caja").

En este caso puntual, tomaré de ejemplo el BS EnsLib.RecordMap.Service.FileService, el cual nos permite leer un archivo (normalmente un csv) desde una carpeta configurable. A veces sucede que el archivo que estamos leyendo es muy grande, y por tanto contiene muchas filas, y nuestra lógica requiera saber exactamente cuando se termino de procesar y además generar un evento que incluso sea procesado por algún Host personalizado.

0
0 225
Artículo Bernardo Linarez · nov 22, 2021 3m read

En algún momento, puede surgir la necesidad de llamar (sentencia CALL en BPL) de manera dinámica, porque hay mucha lógica de negocio compartida por distintos orígenes de datos, que da pie a que esa lógica se comparta y no se individualice cada llamada (CALL).

Esto tiene ventajas a nivel de mantenimiento de la lógica definida, catch de errores y administrar los hilos de ejecución de manera centralizada.

Entonces lo normal es que se defina una sentencia FOREACH que ejecute la sentencia CALL según cada ítem que se necesite.

0
0 183
Artículo Bernardo Linarez · nov 22, 2021 2m read

Tal como sucede con otros tipos de Host, en ciertos casos de uso nos conviene personalizar el comportamiento de algún Business Operation (BO) de caja. En este caso, tomaré de ejemplo el siguiente EnsLib.REST.GenericOperation

En principio, el caso de uso era un simple Pass Through de una petición HTTPRest, por lo que se decidió usar tanto el BS y el BO core de IRIS para reenviarlo. Sin embargo, el destino de esta petición, necesitaba algunos Header por defecto, que no proporcionaba el request original.

0
0 195
InterSystems Official Mario Sanchez Macias · nov 22, 2021

19 de Noviembre de 2021

Los kits de InterSystems incluyen un servidor web Apache que ofrece una práctica manera de interactuar con el Portal de Gestión de Caché/IRIS sin necesidad de instalar un servidor web externo. Sin embargo, este servidor web nunca debería usarse para instancias de producción y se debe instalar un servidor web externo que se ajuste a las necesidades específicas y a los requisitos de seguridad y riesgo de cada cliente.

Pruebas recientes han detectado problemas de seguridad con el servidor web Apache incluido en los kits actuales. Como es una tecnología de terceros que InterSystems no controla, InterSystems recomienda instalar la versión del servidor web obtenida directamente desde Apache y deshabilitar el servidor web Apache incluido. Nuestra documentación incluye instrucciones sobre cómo deshabilitar el servidor web proporcionado con nuestros kits. Apache también ofrece instrucciones de desinstalación, que se pueden encontrar en su página web.

0
0 152
Artículo Ricardo Paiva · nov 12, 2021 21m read

Este curso de formación está dirigido a todas las personas interesadas en conocer el framework de Interoperabilidad de IRIS. Utilizaremos Docker y VSCode.

GitHub: https://github.com/grongierisc/formation-template

1. Formación en Ensemble/Interoperabilidad

El objetivo de esta formación es aprender el framework de interoperabilidad de InterSystems, y en particular el uso de:

  • Producciones
  • Mensajes
  • Business Operations
  • Adaptadores
  • Business Processes
  • Business Services
  • Operaciones y servicios REST

ÍNDICE:

2. Framework

Este es el framework de IRIS.

FrameworkFull

Los componentes que están en el interior de IRIS representan una producción. Los adaptadores de entrada y de salida nos permiten utilizar diferentes tipos de formato como entrada y salida para nuestra base de datos. Las aplicaciones compuestas nos darán acceso a la producción a través de aplicaciones externas como los servicios REST.

Las flechas que están entre todos estos componentes son mensajes. Estos pueden ser solicitudes o respuestas.

3. Adaptación del framework

En nuestro caso, leeremos las líneas desde un archivo CSV y las guardaremos en la base de datos IRIS.

Entonces, añadiremos una operación que nos permitirá guardar los objetos en una base de datos externa, utilizando JDBC. Esta base de datos se ubicará en un contenedor de Docker, utilizando postgre.

Por último, veremos cómo utilizar aplicaciones compuestas para insertar nuevos objetos en nuestra base de datos, o para consultar esta base de datos (en nuestro caso, a través de un servicio REST).

El framework adaptado a nuestro propósito nos ofrece:

FrameworkAdapted

4. Requisitos previos

Para esta formación, necesitarás:

5. Configuración

5.1. Contenedores de Docker

Para tener acceso a las imágenes de InterSystems, hay que ir a esta URL: http://container.intersystems.com. Después de iniciar sesión con nuestras credenciales de InterSystems, obtendremos nuestra contraseña para conectarnos al registro. En el addon de Docker para VSCode, que se encuentra en la pestaña de imágenes, hacemos clic en Conectar Registro, introducimos la misma URL que antes (http://container.intersystems.com) como registro genérico y se nos pedirá que demos nuestras credenciales. El inicio de sesión es el habitual pero la contraseña es la que obtuvimos del sitio web.

A partir de ahí, deberíamos ser capaces de crear y componer nuestros contenedores (con los archivos docker-compose.yml y Dockerfile que se nos dieron).

5.2. Portal de Administración

Abriremos un Portal de Administración. Esto nos dará acceso a una página web desde la que podremos crear nuestra producción. El portal debe estar ubicado en la URL: http://localhost:52775/csp/sys/UtilHome.csp?$NAMESPACE=IRISAPP. Necesitarás las siguientes credenciales:

LOGIN: SuperUser

PASSWORD: SYS

5.3. Guardar el progreso

Una parte de las cosas que haremos se guardarán localmente, pero todos los procesos y producciones se guardan en el contenedor de Docker. Con el fin de conservar todo nuestro progreso, necesitamos exportar todas las clases que se crean desde el Portal de Administración con ayuda del addonObjectScript de InterSystems:

ExportProgress

Tendremos que guardar de esta forma nuestra producción, mapa de registros, business processes y transformaciones de datos. Después de hacerlo, cuando cerremos nuestro contenedor Docker y hagamos la compilación nuevamente, aún tendremos todo nuestro progreso guardado de forma local (por supuesto, hay que hacer esto después de cada cambio que hagamos a través del portal). Para que sea accesible a IRIS de nuevo, tenemos que compilar los archivos exportados (cuando los guardemos, los addons de InterSystems se encargarán del resto).

6. Producciones

Ahora podemos crear nuestra primera producción. Para hacerlo, nos moveremos por los menús [Interoperability] y [Configure]:

ProductionMenu

Ahora hacemos clic en [New], seleccionamos el paquete [Formation] y elegimos un nombre para nuestra producción:

ProductionCreation

Inmediatamente después de crear nuestra producción, hay que hacer clic en la opción [Production Settings], situada encima de la sección [Operations]. En el menú de la barra lateral derecha, tendremos que activar la opción [Testing Enabled] en la sección [Development and Debugging] de la pestaña [Settings] (no te olvides de hacer clic en [Apply]).

ProductionTesting

En esta primera producción añadiremos ahora las business operations.

7. Operaciones

Una business operation (BO) es un tipo de operación específica que nos permitirá enviar solicitudes desde IRIS hacia una aplicación/sistema externo. También se puede utilizar para guardar lo que queramos directamente en IRIS.

Crearemos esas operaciones de forma local, es decir, en el archivo Formation/BO/. Cuando guardemos los archivos los compilaremos en IRIS.

En nuestra primera operación, guardaremos el contenido de un mensaje en la base de datos local.

Para hacerlo, primero necesitamos tener una forma de almacenar este mensaje.

7.1. Creación de nuestra clase de almacenamiento

En IRIS, las clases de almacenamiento extienden el tipo %Persistent. Se guardarán en la base de datos interna.

En nuestro archivo Formation/Table/Formation.cls tenemos lo siguiente:

Class Formation.Table.Formation Extends %Persistent
{

Property Name As %String;

Property Salle As %String;

}

Ten en cuenta que al guardar, de forma automática se añaden líneas adicionales al archivo. Son obligatorias y las añaden los addons de InterSystems.

7.2. Creación de nuestra clase para mensajes

Este mensaje contendrá un objeto Formation, situado en el archivo Formation/Obj/Formation.cls:

Class Formation.Obj.Formation Extends (%SerialObject, %XML.Adaptor)
{

Property Nom As %String;

Property Salle As %String;

}

La clase Message utilizará el objeto Formation, src/Formation/Msg/FormationInsertRequest.cls:

Class Formation.Msg.FormationInsertRequest Extends Ens.Request
{

Property Formation As Formation.Obj.Formation;

}

7.3. Creación de nuestra operación

Ahora que ya tenemos todos los elementos que necesitamos, podemos crear nuestra operación, en el archivo Formation/BO/LocalBDD.cls:

Class Formation.BO.LocalBDD Extends Ens.BusinessOperation
{

Parameter INVOCATION = "Queue";

Method InsertLocalBDD(pRequest As Formation.Msg.FormationInsertRequest, Output pResponse As Ens.StringResponse) As %Status
{
    set tStatus = $$$OK

    try{
        set pResponse = ##class(Ens.Response).%New()
        set tFormation = ##class(Formation.Table.Formation).%New()
        set tFormation.Name = pRequest.Formation.Nom
        set tFormation.Salle = pRequest.Formation.Salle
        $$$ThrowOnError(tFormation.%Save())
    }
    catch exp
    {
        Set tStatus = exp.AsStatus()
    }

    Quit tStatus
}

XData MessageMap
{
<MapItems>
    <MapItem MessageType="Formation.Msg.FormationInsertRequest"> 
        <Method>InsertLocalBDD</Method>
    </MapItem>
</MapItems>
}

}

El MessageMap nos proporciona el método que debemos lanzar, dependiendo del tipo de solicitud (el mensaje que se envió a la operación).

Como podemos ver, si la operación recibió un mensaje del tipo Formation.Msg.FormationInsertRequest, se llamará al método InsertLocalBDD. Este método guardará el mensaje en la base de datos local de IRIS.

7.4. Cómo añadir la operación a la producción

Ahora necesitamos añadir esta operación a la producción. Para hacerlo, utilizaremos el Portal de Administración. Al hacer clic en el signo [+] junto a [Operations], tendremos acceso al [Business Operation Wizard]. Allí, elegiremos la clase de la operación que acabamos de crear en el menú desplegable.

OperationCreation

7.5. Pruebas

Si hacemos doble clic en la operación podremos activarla. Después de hacerlo, al seleccionar la operación e ir a las pestañas [Actions] que están en el menú de la barra lateral derecha, deberíamos poder probar la operación (si no ves la sección para crear la producción, puede que tengas que iniciar la producción si se encuentra detenida).

De este modo, enviaremos a la operación un mensaje del tipo que declaramos anteriormente. Si todo sale bien, los resultados deberían ser similares a los que se muestran a continuación:

OperationTest

Mostrar el registro visual nos permitirá ver lo que ocurrió entre los procesos, servicios y operaciones. Aquí, podemos ver el mensaje que se envía a la operación por parte del proceso, y a la operación cuando envía de vuelta una respuesta (que en este caso solo es una cadena vacía).

8. Business Processes

Los business processes (BP) son la lógica empresarial de nuestra producción. Se utilizan para procesar las solicitudes o retransmitirlas a otros componentes de la producción.

Los business processes se crean dentro del Portal de Administración:

BPMenu

8.1. Business processes simples

8.1.1. Creación del proceso

Ahora estamos en el Diseñador de Business Process. Vamos a crear un business process simple que llamará nuestra operación:

BPAddingCall

8.1.2. Modificación del contexto de un business process

Todos los business processes tiene un contexto. Se compone de una clase para la solicitud, la clase de la entrada, una clase para la respuesta y la clase de la salida. Los business processes solo tienen una entrada y una salida. También es posible agregar propiedades.

Como nuestro business process solo se utilizará para llamar a nuestra business operation, podemos poner la clase del mensaje que hemos creado como clase para la solicitud (no necesitamos una salida ya que solo queremos insertarlo en la base de datos).

BPContext

Ahora, elegiremos el objetivo de la función Call: nuestra business operation. Esa operación, al ser llamada tiene una propiedad callrequest. Necesitamos vincular esa propiedad callrequest con la solicitud del business process (ambos pertenecen a la clase Formation.Msg.FormationInsertRequest) y para ello, hacemos clic en la función Call y utilizaremos el creador de peticiones:

BPBindRequests

Ahora podemos guardar este business process (en el paquete 'Formation.BP' y, por ejemplo, con el nombre 'InsertLocalBDD' o 'Main'). Al igual que las operaciones, pueden crearse instancias de los procesos y se pueden probar mediante la Configuración de la producción, aunque para esto necesitan compilarse previamente (en la pantalla del Business Process Designer).

Por ahora, nuestro proceso solo pasa el mensaje a nuestra operación. Vamos a aumentar la complejidad para que el business process tome como entrada una línea de un archivo CSV.

8.2. Cómo hacer que el business process lea líneas CSV

8.2.1. Creación de un mapa de registro

Para leer un archivo y poner su contenido en otro archivo, necesitamos un Mapa de Registros (RM). En el menú [Interoperability > Build] del Portal de Administración hay un servicio para mapear los registros, especializado en archivos CSV:

RMMenu

Crearemos el servicio para elaborar mapas de esta manera:

RMCreation

Ahora deberías tener el siguiente Mapa de Registros:

RMDetails

Ahora que el mapa está creado, debemos generarlo (con el botón Generate). También debemos efectuar una Transformación de datos desde el formato del Mapa de registros y un mensaje de inserción.

8.2.2. Creación de una transformación de datos

Encontraremos el Generador para la Transformación de datos (DT) en el menú [Interoperability > Builder]. A continuación, crearemos nuestra DT de esta forma (si no encuentras la clase Formation.RM.Csv.Record, tal vez no se generó el Mapa de Registros):

DTCreation

Ahora, podemos mapear los diferentes campos juntos:

DTMap

8.2.3. Añadir la transformación de datos al business process

Lo primero que debemos modificar es la clase de la solicitud del business process, ya que necesitamos tener una entrada en el Mapa de Registros que creamos.

BP2ChangeContext

Entonces, podemos añadir nuestra transformación (el nombre del proceso no cambia nada, a partir de aquí elegimos llamarlo Main):

BP2AddingTransform

La actividad de transformación tomará la solicitud del business process (un registro del archivo CSV, gracias a nuestro servicio para mapear los registros) y la transformará en un mensaje FormationInsertRequest. Si deseamos almacenar ese mensaje para enviarlo al business operation, necesitamos añadir una propiedad al contexto del business process.

BP2MsgContext

Ahora podemos configurar nuestra función de transformación para que tome su entrada como entrada del business process y guarde su salida en la propiedad recién creada. El origen y el objetivo de la transformación RmToMsg son request y context.Msg, respectivamente:

BP2RmToMsg

Tenemos que hacer lo mismo para Call BO. Su entrada, o callrequest, es el valor almacenado en context.msg:

BP2CallBO

Al final, el flujo en el business process puede representarse de esta manera:

BP2Diagram

8.2.4. Configuración de la producción

Con el signo [+], podemos añadir nuestro nuevo proceso a la producción (si aún no lo hemos hecho). También necesitamos un servicio genérico para utilizar el Mapa de Registros, para ello utilizamos EnsLib.RecordMap.Service.FileService (lo añadimos con el botón [+] que está junto a los servicios). A continuación, parametrizamos este servicio:

ServiceParam

Ahora deberíamos poder probar nuestro business process.

8.2.5. Pruebas

Probamos toda la producción de esta manera:

TestProductionCSV

En el menú System Explorer > SQL, puedes ejecutar el comando

SELECT 
ID, Name, Salle
FROM Formation_Table.Formation

para ver los objetos que acabamos de guardar.

9. Obtener acceso a una base de datos externa usando JDBC

En esta sección, crearemos una operación para guardar nuestros objetos en una base de datos externa. Utilizaremos la API de JDBC, así como el otro contenedor Docker que configuramos, con postgre en él.

9.1. Creación de nuestra nueva operación

Nuestra nueva operación, en el archivo Formation/BO/RemoteBDD.cls es así:

Include EnsSQLTypes

Class Formation.BO.RemoteBDD Extends Ens.BusinessOperation
{

Parameter ADAPTER = "EnsLib.SQL.OutboundAdapter";

Property Adapter As EnsLib.SQL.OutboundAdapter;

Parameter INVOCATION = "Queue";

Method InsertRemoteBDD(pRequest As Formation.Msg.FormationInsertRequest, Output pResponse As Ens.StringResponse) As %Status
{
    set tStatus = $$$OK

    try{
        set pResponse = ##class(Ens.Response).%New()
        set ^inc = $I(^inc)
        set tInsertSql = "INSERT INTO public.formation (id, nom, salle) VALUES(?, ?, ?)"
        $$$ThrowOnError(..Adapter.ExecuteUpdate(.nrows,tInsertSql,^inc,pRequest.Formation.Nom, pRequest.Formation.Salle ))
    }
    catch exp
    {
        Set tStatus = exp.AsStatus()
    }

    Quit tStatus
}

XData MessageMap
{
<MapItems>
    <MapItem MessageType="Formation.Msg.FormationInsertRequest"> 
        <Method>InsertRemoteBDD</Method>
    </MapItem>
</MapItems>
}

}

Esta operación es similar a la primera que creamos. Cuando reciba un mensaje del tipo Formation.Msg.FormationInsertRequest, utilizará un adaptador para ejecutar solicitudes SQL. Esas solicitudes se enviarán a nuestra base de datos de postgre.

9.2. Configuración de la producción

Ahora, desde el Portal de Administración, crearemos una instancia de esa operación (añadiéndola con el signo [+] en la producción).

También necesitaremos añadir el JavaGateway para el controlador JDBC en los servicios. El nombre completo de este servicio es EnsLib.JavaGateway.Service.

JDBCProduction

Ahora necesitamos configurar nuestra operación. Como hemos configurado un contenedor postgre, y conectado su puerto 5432, los valores que necesitamos en los siguientes parámetros son:

DSN: jdbc:postgresql://db:5432/DemoData

Controlador de JDBC: org.postgresql.Driver

JDBC Classpath: /tmp/iris/postgresql-42.2.14.jar

JDBCParam

Finalmente, necesitamos configurar las credenciales para tener acceso a la base de datos remota. Para ello, necesitamos abrir el Visualizador de credenciales:

JDBCCredentialMenu

Tanto el nombre de usuario como la contraseña son DemoData, como lo configuramos en el archivo docker-compose.yml.

JDBCCredentialCreation

De vuelta a la producción, podemos añadir "Postgre" en el campo [Credential] en la configuración de nuestra operación (debería estar en el menú desplegable). Antes de que podamos probarlo, debemos añadir el JGService a la operación. En la pestaña [Settings], en [Additional Settings]:

JDBCService

9.3. Pruebas

Cuando se están haciendo pruebas el registro visual debe mostrar que tuvimos éxito:

JDBCTest

Conectamos correctamente una base de datos externa.

9.4. Ejercicio

Como ejercicio, podría ser interesante modificar BO.LocalBDD para que devuelva un booleano, que le dirá al business process que llame a BO.RemoteBDD dependiendo del valor de ese booleano.

Sugerencia: Esto se puede hacer cambiando el tipo de respuesta que devuelve LocalBDD, añadiendo una nueva propiedad al contexto y utilizando la actividad if en nuestro business process.

9.5. Solución

Primero, necesitamos tener una respuesta de nuestra operación LocalBDD. Vamos a crear un nuevo mensaje, en Formation/Msg/FormationInsertResponse.cls:

Class Formation.Msg.FormationInsertResponse Extends Ens.Response
{

Property Double As %Boolean;

}

Después, cambiamos la respuesta de LocalBDD por esa respuesta y establecemos el valor de su booleano de forma aleatoria (o no):

Method InsertLocalBDD(pRequest As Formation.Msg.FormationInsertRequest, Output pResponse As Formation.Msg.FormationInsertResponse) As %Status
{
    set tStatus = $$$OK

    try{
        set pResponse = ##class(Formation.Msg.FormationInsertResponse).%New()
        if $RANDOM(10) < 5 {
            set pResponse.Double = 1
        } 
        else {
            set pResponse.Double = 0
        }
...

Ahora crearemos un nuevo proceso (copiado del que hicimos), donde añadiremos una nueva propiedad de contexto, de tipo %Boolean:

ExerciseContext

Esta propiedad se completará con el valor del callresponse.Double de nuestra llamada de operación (necesitaremos establecer [Response Message Class] en nuestra nueva clase de mensaje):

ExerciseBinding

A continuación, añadimos una actividad if, con la propiedad context.Double como condición:

ExerciseIf

MUY IMPORTANTE: necesitamos desmarcar Asynchronous en la configuración de nuestra LocallBDD Call, o la actividad if se activará antes de que reciba la respuesta booleana.

Finalmente configuramos nuestra actividad de llamada como un objetivo RemoteBDD BO:

ExerciseRemoteCall

Para completar la actividad if, necesitamos arrastrar otro conector desde la salida del if al triángulo join que se encuentra debajo. Como no haremos nada si el valor booleano es falso, dejaremos este conector vacío.

Después de compilar y crear instancias, deberíamos poder probar nuestro nuevo proceso. Para ello, necesitamos cambiar Target Config Name de nuestro servicio de archivos.

En el seguimiento, deberíamos tener aproximadamente la mitad de los objetos leídos en el csv guardados también en la base de datos remota.

10. Servicio REST

En esta parte, crearemos y utilizaremos un Servicio REST.

10.1. Creación del servicio

Para crear un servicio REST, necesitamos una clase que extienda %CSP.REST, en Formation/REST/Dispatch.cls tenemos:

Class Formation.REST.Dispatch Extends %CSP.REST
{

/// Ignore any writes done directly by the REST method.
Parameter IgnoreWrites = 0;

/// By default convert the input stream to Unicode
Parameter CONVERTINPUTSTREAM = 1;

/// The default response charset is utf-8
Parameter CHARSET = "utf-8";

Parameter HandleCorsRequest = 1;

XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
  <!-- Get this spec -->
  <Route Url="/import" Method="post" Call="import" />
</Routes>
}

/// Get this spec
ClassMethod import() As %Status
{
  set tSc = $$$OK

  Try {

      set tBsName = "Formation.BS.RestInput"
      set tMsg = ##class(Formation.Msg.FormationInsertRequest).%New()

      set body = $zcvt(%request.Content.Read(),"I","UTF8")
      set dyna = {}.%FromJSON(body)

      set tFormation = ##class(Formation.Obj.Formation).%New()
      set tFormation.Nom = dyna.nom
      set tFormation.Salle = dyna.salle

      set tMsg.Formation = tFormation

      $$$ThrowOnError(##class(Ens.Director).CreateBusinessService(tBsName,.tService))

      $$$ThrowOnError(tService.ProcessInput(tMsg,.output))

  } Catch ex {
      set tSc = ex.AsStatus()
  }

  Quit tSc
}

}

Esta clase contiene una ruta para importar un objeto, vinculado al verbo POST:

<Routes>
  <!-- Get this spec -->
  <Route Url="/import" Method="post" Call="import" />
</Routes>

El método de importación creará un mensaje que se enviará a un business service.

10.2. Añadir nuestro Business Service (BS)

Vamos a crear una clase genérica que dirigirá todas sus solicitudes hacia TargetConfigNames. Este objetivo se configurará cuando creemos una instancia de este servicio. En el archivo Formation/BS/RestInput.cls tenemos:

Class Formation.BS.RestInput Extends Ens.BusinessService
{

Property TargetConfigNames As %String(MAXLEN = 1000) [ InitialExpression = "BuisnessProcess" ];

Parameter SETTINGS = "TargetConfigNames:Basic:selector?multiSelect=1&context={Ens.ContextSearch/ProductionItems?targets=1&productionName=@productionId}";

Method OnProcessInput(pDocIn As %RegisteredObject, Output pDocOut As %RegisteredObject) As %Status
{
    set status = $$$OK

    try {

        for iTarget=1:1:$L(..TargetConfigNames, ",") {
            set tOneTarget=$ZStrip($P(..TargetConfigNames,",",iTarget),"<>W")  Continue:""=tOneTarget
            $$$ThrowOnError(..SendRequestSync(tOneTarget,pDocIn,.pDocOut))
        }
    } catch ex {
        set status = ex.AsStatus()
    }

    Quit status
}

}

Volviendo a la configuración de la producción, añadimos el servicio de la manera habitual. En [Target Config Names], ponemos nuestro BO LocalBDD:

RESTServiceSetup

Para utilizar este servicio, necesitamos publicarlo. Para ello, usamos el menú [Edit Web Application]:

RESTServicePublish

10.3. Pruebas

Por último, podemos probar nuestro servicio con cualquier tipo de cliente REST:

RESTTest

Conclusión

A través de esta formación, hemos creado una producción que es capaz de leer líneas desde un archivo csv y guardar los datos leídos tanto en la base de datos de IRIS como en una base de datos externa, utilizando JDBC. También añadimos un servicio REST para utilizar el verbo POST para guardar nuevos objetos.

Hemos descubierto los principales elementos del framework de interoperabilidad de InterSystems.

Lo hemos hecho utilizando Docker, VSCode y el Portal de Administración de InterSystems IRIS.

0
0 319
Artículo Alberto Fuentes · nov 4, 2021 2m read

Algunos de vosotros no conoceréis esta limitación o problema conocido que se produce en los Procesos de Negocio (Business Processes) basados en BPL.

Aquellos que no estabais al tanto quizá os habéis encontrado esto:

ERROR <Ens>ErrBPTerminated: Terminating BP <my_process_name> # due to error:

ERROR #7201: Datatype value 'xxS6xxS6...xxS6' length longer than MAXLEN allowed of 5

Y / o:

ERROR #5802: Datatype validation failed on property '<my_process_class>.Thread1:%HandlerStack', with value equal to "xxS6xxS6...xxS6"

Esta es la información que encontramos en la documentación al respecto:

Restricción de la actividad «Scope» dentro de un bucle en BPL

Bajo ciertas condiciones, los bucles que contienen actividades «Scope» (Ámbito) y tienen un gran número de repeticiones, pueden provocar un error. Si es posible, define la actividad «Scope» para que incluya el bucle en vez de que se defina dentro del bucle.

Así que si tienes un bucle dentro de un BPL, e introduces un «Scope» (Ámbito) en él (y probablemente una actividad «Continue»), y tienes, por ejemplo, unas 15 o más iteraciones, se producirá el error anterior.

Este es un ejemplo de este tipo de bucles:

Así es como se vería el error:

La solución, como se menciona en la documentación, es colocar el bucle dentro de la actividad «Scope», en vez de que el «Scope» esté dentro del bucle.

Espero que esto ayude a cualquiera que se encuentre con este error.

0
0 106
Anuncio Kurro Lopez · oct 21, 2021

El equipo de certificación de InterSystems está preparando un examen de certificación de Especialista en integración Intersystems IRIS (InterSystems IRIS Integration Specialist) y está buscando expertos en la materia (EEM) (SME, en inglés Subject Matter Expert) de nuestra comunidad para que le ayuden a redactar preguntas. Usted, como miembro valioso de la comunidad de InterSystems, conoce los desafíos de trabajar con nuestra tecnología y lo que se necesita para tener éxito en su trabajo. A cambio de su ayuda, se le compensará hasta con $500 por trabajo asignado. Un trabajo asignado,

0
0 82
Artículo Muhammad Waseem · oct 20, 2021 2m read

En este artículo demostraré lo siguiente:

  • Cómo actualizar ReferencesRange (OBX: 7) contra ObservationIdentifier (OBX: 3.1) [TestCode] de la base de datos mediante la función de utilidad personalizada
  • Cómo actualizar Abnormal Flag (OBX: 8) contra ObservationIdentifier (OBX: 3.1) [TestCode] y ObservationValue (OBX: 5) [Resultado] desde la función de utilidad de base de datos
  • Mensaje de ruta basado en un Abnormal Flag (OBX: 8)
0
0 142
Pregunta Yone Moreno · oct 14, 2021

En primer lugar, gracias por su tiempo leyendo esta pregunta y gracias por su ayuda.

Tenemos el siguiente caso de uso: necesitaríamos enviar con MTOM un zip que contenga un csv

Hemos leído, investigado, indagado:

https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...

https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...

https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...

Necesitaríamos replicar cómo SOAPUI envía un zip con un csv como archivo adjunto en una solicitud SOAP, empleando Ensemble

9
0 447
Artículo Muhammad Waseem · oct 5, 2021 2m read

Oí hablar del Banco de Mensajes (Message Bank) cuando comenzamos a rediseñar una producción de Health Connect para que se ejecutara en contenedores en la nube. Como habría varios contenedores de IRIS, se nos indicó que utilizáramos el Banco de Mensajes como un sitio único para ver los mensajes y registros de todos los contenedores.

¿Cómo funciona Message Bank?

Añadí la operación del Banco de Mensajes a nuestra Producción de Interoperabilidad. Envía automáticamente mensajes y registros de eventos al Banco de Mensajes.

0
0 118
Pregunta Kurro Lopez · sep 23, 2021

Hola comunidad,

Tengo una clase cliente SOAP que conecta con un WS Service. Esta estructura y configuracion es la misma para varios proveedores que están integerados con mi solución.

Si llamo a un proveedor, devuelve el XML esperado. Pero hay un proveedor que lanza un error:

ERROR #6243: HTTP request to SOAP WebService returned response with unexpected CONTENT-TYPE: application/wsdl+xml

He intentado asignar el ContentType al adapter.%Client con este valor, pero no funciona.

Si lo invoco usando SOAP UI, con el mismo Soap Envelop, funciona correctamente y el Content-Type es text/xml

7
0 556
Artículo Eduardo Anglada · sep 7, 2021 3m read
Este es un ejemplo de código que funciona en IRIS 2020.1 y en Caché 2018.1.3 
No se mantendrá sincronizado con las nuevas versiones.  
Y NO cuenta con el servicio de soporte de InterSystems.
De vez en cuando, puedes encontrarte una situación en la que, por diferentes razones, ODBC es la única opción para acceder a un sistema remoto. Lo cual es suficiente mientras necesites examinar o cambiar tablas. Pero no puedes ejecutar directamente algunos comandos o cambiar algunos globals.
0
0 154
Artículo Mathew Lambert · sep 1, 2021 2m read

¡Hola a todos!

Hace poco aprendí algo nuevo mientras trabajaba en un problema con el Centro de Soporte Internacional (WRC), y quería compartirlo con todos por si pudiera ayudar a alguien más.

Escenario:

Tienes archivos que se escriben inexplicablemente en una carpeta de tu servidor y, debido a la cantidad de archivos en la carpeta y al rendimiento general del sistema, no es posible trabajar sobre los archivos para localizar el origen.

0
0 1329