Envío y recepción de mensajes entre InterSystems IRIS y Azure Service Bus
En este ejemplo he buscado el punto intermedio entre una demo muy simple y una arquitectura muy complicada: una integración pequeña, clara y útil para entender cómo conectar InterSystems IRIS con Azure Service Bus usando una producción de interoperabilidad de IRIS que aprovecha Embedded Python para utilizar la librería oficial de Azure.
La idea es sencilla:
- IRIS envía mensajes a una cola de Azure Service Bus mediante un
Business Operation. - IRIS recibe mensajes desde esa misma cola mediante un
Inbound Adaptery unBusiness Service. - Los componentes de interoperabilidad son componentes de IRIS.
- Dentro de esos componentes, Embedded Python permite usar el SDK
azure-servicebussin salir del entorno de IRIS.
Dicho de otra forma: una solución en IRIS que usa Embedded Python donde corresponda para integrarse con Azure.
Qué hace este ejemplo
Este ejemplo no intenta cubrir todos los casos posibles de Azure Service Bus. No hay dead-letter queues, reintentos sofisticados ni un comité de arquitectura reunido alrededor de un diagrama.
Lo que sí muestra, de forma intencionadamente simple, es un patrón muy útil:
Flujo de salida
Mensaje IRIS -> Business Operation -> Azure Service Bus Queue
El componente principal es:
Demo.Azure.ServiceBus.Outbound.BusinessOperation
Este Business Operation:
- inicializa el cliente de Azure una sola vez en
OnInit(), - reutiliza el
sendermientras el proceso está vivo, - envía el cuerpo del mensaje,
- y puede mapear propiedades como
MessageId,CorrelationId,Subjecty propiedades de aplicación en JSON.
Flujo de entrada
Azure Service Bus Queue -> Inbound Adapter -> Business Service -> Mensaje IRIS
Los componentes principales son:
Demo.Azure.ServiceBus.Inbound.AdapterDemo.Azure.ServiceBus.Inbound.BusinessService
El adaptador:
- recibe mensajes desde Azure usando
PEEK_LOCK, - trabaja por lotes,
- conserva los mensajes bloqueados mientras IRIS los procesa,
- hace
completesi todo va bien, - y hace
abandonsi falla el procesamiento.
Este detalle importa bastante. No estamos simplemente "leyendo una cola", estamos integrando un patrón sencillo pero realista de recepción fiable.
Arquitectura del ejemplo
La producción incluida en el proyecto es Demo.Production y contiene dos componentes principales:
Azure ServiceBus SenderAzure ServiceBus Receiver
Además hay una operación Dummy (desactivada) para que el flujo de entrada pueda inspeccionarse dentro de IRIS sin añadir ruido adicional.
La estructura del ejemplo es esta:
.
|-- README.md
|-- docker-compose.yml
`-- iris
|-- Dockerfile
|-- requirements.txt
|-- iris.script
`-- src
`-- Demo
|-- Production.cls
`-- Azure
`-- ServiceBus
|-- Outbound
| |-- BusinessOperation.cls
| |-- Request.cls
| `-- Response.cls
`-- Inbound
|-- Adapter.cls
|-- BusinessService.cls
`-- Request.cls
Por qué usar Embedded Python aquí
Este ejemplo aprovecha una capacidad nativa de IRIS, Embedded Python, para usar la librería oficial de Azure directamente dentro de los componentes de interoperabilidad.
IRIS sigue definiendo los componentes, su ciclo de vida y el procesamiento interoperable, mientras que Embedded Python se usa dentro de esos mismos componentes para llamar al SDK de Azure Service Bus. Esto permite:
- aprovechar una librería oficial y madura de Azure,
- evitar reinventar llamadas HTTP o AMQP a mano,
- y mantener el código de integración bastante legible.
En la práctica, el patrón queda así:
- IRIS define y ejecuta la producción de interoperabilidad.
- En los propios componentes de entrada y salida, Embedded Python invoca la librería de Azure.
- El procesamiento, la trazabilidad y el control del flujo siguen dentro de IRIS.
Eso hace que la integración sea coherente: no añadimos una pieza externa paralela, sino que ampliamos los componentes de IRIS con acceso directo a librerías Python cuando hace falta.
Preparando el entorno
El proyecto arranca con Docker y levanta una instancia de InterSystems IRIS Community con el código ya cargado.
Requisitos
Necesitarás:
- Git
- Docker y Docker Compose
- una suscripción de Azure (tienes opción de una prueba gratuita)
- un namespace de Azure Service Bus
- al menos una cola creada en ese namespace
Si todavía no tienes preparada la parte de Azure Service Bus, puedes apoyarte en la guía oficial de Microsoft para crear el namespace, la cola y obtener una connection string de prueba:
La dependencia Python usada por el ejemplo es:
azure-servicebus
Arranque del contenedor
git clone <tu-repo-o-fork>
cd iris-azure-servicebus-interop
docker compose build
docker compose up -d
Cuando el contenedor esté levantado, puedes entrar al Management Portal en:
http://localhost:52776/csp/sys/UtilHome.csp
Credenciales del ejemplo:
superuser / SYS

El ejemplo arranca en Docker y deja la producción lista para abrirse desde el Management Portal de IRIS.
Cómo funciona el envío de mensajes
El flujo de salida está implementado en Demo.Azure.ServiceBus.Outbound.BusinessOperation.
La secuencia es esta:
OnInit()crea elServiceBusClienty elQueueSender.OnMessage()recibe unDemo.Azure.ServiceBus.Outbound.Request.- Se llama al método Python
PySendMessage(). - El mensaje se publica en la cola.
El objeto de request permite enviar:
BodyMessageIdCorrelationIdSubjectApplicationPropertiesJSON
Eso ya da bastante juego para pruebas realistas. Puedes transportar metadatos útiles para trazabilidad y correlación.

Configuración básica del Business Operation encargado de publicar mensajes en la cola de Azure Service Bus.
Cómo funciona la recepción de mensajes
La parte de entrada está implementada entre Demo.Azure.ServiceBus.Inbound.Adapter y Demo.Azure.ServiceBus.Inbound.BusinessService.
Aquí está el punto técnico más interesante del ejemplo.
El adaptador recibe por lotes
En OnTask(), el adaptador llama a PyReceiveBatch() para pedir varios mensajes a Azure.
Cada mensaje recibido se transforma en un objeto Demo.Azure.ServiceBus.Inbound.Request, que incluye:
BodyMessageIdCorrelationIdSubjectContentTypeApplicationPropertiesJSONSequenceNumberDeliveryCountSettlementToken
El SettlementToken tiene un papel clave
Como el objeto recibido del SDK de Azure se mantiene dentro del contexto manejado por Embedded Python en IRIS, el adaptador genera un token interno para poder:
- completar el mensaje si IRIS lo procesa correctamente,
- o abandonarlo si hay error.
Ese diseño mantiene limpia la interacción entre ObjectScript y Embedded Python dentro del propio componente. En lugar de intentar mover objetos complejos del SDK de Azure entre contextos, el adaptador trabaja con una referencia simple y controlada.
El Business Service procesa y enruta
El BusinessService de este ejemplo hace algo deliberadamente simple:
- escribe trazas con el
MessageIdy el cuerpo, - y reenvía el mensaje a un destino
Dummy(desactivado): se usa en este ejemplo para centrarnos en inspeccionar el flujo extremo a extremo en la producción sin mezclar reglas u otros componentes.
Cómo probar el ejemplo
Una vez levantado IRIS, abre:
- Interoperability
- Configure
- Production
Demo.Production
Verás los componentes del ejemplo y podrás configurar:
ConnectionStringQueueNameMaxMessageCountMaxWaitTime
Prueba 1: enviar un mensaje desde IRIS a Azure Service Bus
Desde el portal de gestión, dentro de la producción, abre el componente:
Azure ServiceBus Sender
Después entra en:
Test
Ahí puedes enviar un objeto Demo.Azure.ServiceBus.Outbound.Request rellenando los campos del mensaje con valores como:
{
"Body": "hello from iris",
"MessageId": "msg-001",
"CorrelationId": "corr-001",
"Subject": "demo",
"ApplicationPropertiesJSON": "{\"source\":\"iris\",\"env\":\"demo\"}"
}
Una vez lanzada la prueba, revisa la cola en Azure Portal o en Service Bus Explorer para confirmar que el mensaje ha llegado.


Mensaje publicado desde IRIS y ya visible en la cola de Azure Service Bus con sus propiedades principales.
Prueba 2: recibir mensajes desde Azure en IRIS
Envía uno o varios mensajes a la cola desde Azure.
Luego:
- inicia la producción si no está activa,
- abre el Message Viewer,
- revisa las trazas generadas por
Azure ServiceBus Receiver.
Deberías ver:
- el
MessageId, - el cuerpo del mensaje,
- y el recorrido interno dentro de la producción.

Trazabilidad del mensaje dentro de IRIS: recepción desde Azure, procesamiento en el Business Service y continuidad del flujo en la producción.
Un punto importante sobre seguridad
El ejemplo actual usa connection string porque es la forma más sencilla de hacer que funcione. Para aprender, esta forma está bien. Para producción, conviene subir el listón.
Las alternativas más razonables son:
- usar credenciales de IRIS y reconstruir la conexión de forma controlada,
- o ir a un enfoque passwordless con
DefaultAzureCredential.
El repositorio ya incluye una nota técnica sobre este segundo enfoque en:
docs/service-principal-passwordless.md
Si vas reutilizar este ejemplo, esta parte merece que le eches un vistazo.
¿Por qué te puede resultar útil este ejemplo?
Hay varias cosas que hacen que este ejemplo te pueda ser útil como base para otros desarrollos:
- separa bien la responsabilidad de interoperabilidad y la de acceso al broker,
- reutiliza el cliente de Azure en lugar de reconectar para cada mensaje,
- modela explícitamente la entrada y la salida con clases de request/response,
- y muestra un patrón de recepción fiable con
peek-lock,completeyabandon.
No es un “hello world” disfrazado interoperabilidad. Tampoco es un monstruo de complejidad. Precisamente por eso te puede resultar práctico.
Posibles siguientes pasos
Si quieres evolucionar este ejemplo, hay varias ampliaciones naturales:
- autenticación passwordless real con
DefaultAzureCredential, - soporte para topics y subscriptions,
- envío a dead-letter queue,
- validación de payloads,
- routing a operaciones reales de IRIS,
- reintentos y observabilidad más detallada.
Conclusión
Este ejemplo muestra una forma sencilla de integrar InterSystems IRIS con Azure Service Bus:
- usando las capacidades nativas de interoperabilidad de IRIS,
- aprovechando Embedded Python como parte del propio modelo de desarrollo en IRIS,
- y utilizando desde esos componentes el SDK oficial de Azure.
Si trabajas con IRIS y necesitas conectar colas de Azure, puedes utilizar este ejemplo como punto de partida.