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
0
0 129
Artículo Alberto Fuentes · oct 29, 2021 2m read

ObjectScript tiene diferentes formas para gestionar errores (códigos %Status, %Exception, SQLCODE, etc). La mayor parte del código de sistema utiliza códigos pero las son en ocasiones más fáciles de gestionar.

Si tienes que trabajar o mantener aplicaciones con cierto recorrido seguramente acabes lidiando con distintas técnicas de gestión de errores. A continuación os dejo una chuleta u hoja de trucos que puede servir como referencia. ¡Espero que os sea útil!

0
0 133
Artículo Alberto Fuentes · oct 19, 2021 5m read

¡Hola desarrolladores!

Últimamente he estado probando el módulo csvgen y buscaba un fichero CSV para probar. Resulta que encontré un fichero muy interesante en Data.World con estadísticas sobre los episodios de Game of Thrones (Juego de Tronos). Estadísticas sobre muertes 😱.

¡Han documentado todos los asesinatos a lo largo de las 8 temporadas y han anotado dónde, quién, qué clan y con qué arma ha matado a otro personaje!

Así que lo he importado para hacer un cuadro de mando con IRIS Analytics.

No te preocupes, Jon. Con este cuadro de mando podremos hacer que averigües algo.

0
0 325
Artículo Alberto Fuentes · oct 7, 2021 2m read

¡Hola desarrolladores!

Con frecuencia, cuando colaboramos con el repositorio de alguien en GitHub, seguimos el siguiente ciclo:

  1. Fork: crear nuestra bifurcación del repositorio
  2. Clone: clonar una copia local de nuestro repositorio bifurcado
  3. Realizar nuestros cambios y guardarlos con un Commit en nuestra copia local
  4. Push: publicar nuestros cambios al repositorio clonado de GitHub
  5. Hacer Pull-Request para solicitar incorporar nuestros cambios desde nuestro fork — bifurcación — al repositorio original
  6. Y si todo va bien se hará un Merge — fusión o incorporación — con nuestros cambios en el repositorio original

¡Todo esto es genial y funciona bien!

Y si queremos realizar una segunda colaboración justo después de llevar a cabo un Merge , es necesario que primero realicemos un Fetch upstream en nuestro repositorio clonado para que tengamos disponibles los cambios actualizados que incorporamos al repositorio original a través del Pull Request.

Los más frikies de git lo hacen muy fácilmente, pero muchos terminamos simplemente por eliminar nuestro primer fork y crear otro nuevo.

0
0 312
Artículo Alberto Fuentes · sep 20, 2021 2m read

¡Hola desarrolladores!

Otra forma de empezar a utilizar InterSystems Objectscript Package Manager es descargar las imágenes pre-construidas de InterSystems IRIS Community Edition o IRIS for Health Community Edition.

Estas imágenes de IRIS están desplegadas en DockerHub y puedes ejecutarlas directamente con este comando:

docker run --rm -p 52773:52773 --init --name my-iris -d intersystemsdc/iris-community:2021.1.0.215.0-zpm
0
0 123
Artículo Alberto Fuentes · sep 13, 2021 2m read

¡Hola desarrolladores!

A veces necesitamos importar datos CSV de forma programática en InterSystems IRIS desde un fichero o una URL. Y esperamos además que automáticamente se genere una clase con los tipos de datos adecuados y los datos importados.

Echadle un ojo al módulo csvgen en Open Exchange que hace exactamente eso que hemos descrito.

Si necesitas importar un fichero CSV en IRIS puedes hacer esto:

USER>do ##class(community.csvgen).Generate("/usr/data/titanic.csv",,"Data.Titanic")

Class name: Data.Titanic
Header: PassengerId INTEGER,Survived INTEGER,Pclass INTEGER,Name VARCHAR(250),Sex VARCHAR(250),Age INTEGER,SibSp INTEGER,Parch INTEGER,Ticket VARCHAR(250),Fare MONEY,Cabin VARCHAR(250),Embarked VARCHAR(250)
Records imported: 891
USER>
0
0 257
Artículo Alberto Fuentes · ago 13, 2021 4m read

InterSystems IRIS ofrece la posibilidad de crear interfaces REST con el enfoque spec-first, esto es, partiendo de las especificaciones de la API.

Puedes echarle un vistazo a este artículo para más información al respecto : https://es.community.intersystems.com/post/cómo-desarrollar-una-api-rest-con-un-enfoque-spec-first.

Algo muy práctico que tiene este enfoque y la propia OpenAPI, es la definición de los objetos que se van a intercambiar. El comando do ^%REST crea las rutas y los métodos asociados, pero sin embargo no crea las definiciones de los objetos.

0
0 353
Artículo Alberto Fuentes · jul 6, 2021 7m read

Hace un tiempo se publicó el paquete AppS.REST. AppS.REST es un framework para exponer fácilmente clases persistentes de IRIS como recursos REST. Las clases que tienen habilitado AppS.REST soportan operaciones CRUD con poco esfuerzo del desarrollador, acortando la brecha entre los datos persistentes en IRIS y los consumidores de datos, como una aplicación front-end de Angular.

¡Pero las clases de IRIS son mucho más que una simple definición para cargar y guardar registros individuales! Este artículo tiene como objetivo destacar algunas maneras de aprovechar el poder de IRIS en tus aplicaciones REST.  Usando la aplicación de ejemplo Phone.Contact, veremos el soporte de consultas incluido en AppS.REST, el uso de consultas de clase y finalmente los métodos ObjectScript.

0
1 114
Artículo Alberto Fuentes · jul 1, 2021 1m read

Existe una forma muy sencilla de añadir los certificados de una Autoridad Certificadora a las configuraciones de TLS / SSL en InterSystems IRIS en Windows y Mac.

Puedes pedirle a IRIS que utilice el almacén de certificados de tu sistema operativo indicando %OSCertificateStore en el campo para "File containing Trusted Certificate Authority X.509 certificate(s)".

Aquí tenemos un ejemplo de cómo hacerlo:

0
0 169
Artículo Alberto Fuentes · jun 22, 2021 4m read

En este artículo, ejecutaremos un clúster InterSystems IRIS usando Docker y archivos CPF combinados - una nueva característica que permite configurar servidores con facilidad.

En UNIX® y Linux, puedes modificar el archivo predeterminado iris.cpf utilizando un archivo CPF combinado declarativo. Un archivo combinado es un CPF parcial en el que se establecen los valores deseados que queramos que tenga una instancia al iniciar. La operación de combinación en CPF sólo funciona una vez para cada instancia.

Nuestra arquitectura de clúster es muy sencilla, consistirá en un Nodo 1 (nodo maestro) y dos Nodos de datos (echa un vistazo a todas las funciones disponibles). Desafortunadamente, docker-compose no puede desplegar en diferentes servidores (aunque puede desplegar a hosts remotos), por lo que esto es útil para el desarrollo local de modelos de datos que utilicen sharding, pruebas, etc. Para el despliegue en producción de un cluster de estar características, debes utilizar ICM o IKO.

1
0 168
Artículo Alberto Fuentes · jun 18, 2021 1m read

Hola Comunidad! Aprovechando la publicación de la nueva versión IRIS 2021.1 y también de IAM 2.3 os paso los ejercicios de un taller (workshop) sobre desarrollo de APIs REST y gestión de las mismas utilizando InterSystems API Manager.

Contiene ejercicios paso a paso para:

  • Crear APIs REST desde sus especificaciones OpenAPI.
  • Añadir, opcionalmente, la API creada a una producción de interoperabilidad.
  • Gestión básica de la API en InterSystems API Manager (consumidores, limitación, autenticación).
  • Planteamiento de algunos escenarios más complejos en InterSystems API Manager como balanceo de carga, o enrutamiento por cabecera.

Lo tenéis todo en la aplicación de Open Exchange vinculada.

0
0 151
Artículo Alberto Fuentes · mayo 25, 2021 12m read

En este artículo, me gustaría hablar sobre el enfoque spec-first para el desarrollo de una API REST.

Mientras que el desarrollo tradicional code-first de una API REST es así:

  • Escribir el código
  • Habilitarlo en REST
  • Documentarlo (como una API REST)

Spec-first sigue los mismos pasos, pero a la inversa. Comenzamos con una especificación, — que también actúa como documentación — , generamos el código base de la aplicación REST a partir de ella, y finalmente escribimos la lógica de negocio concreta que nos haga falta.

Esto ofrece varias ventajas:

1
0 1027
Artículo Alberto Fuentes · mayo 20, 2021 1m read

¡Hola desarrolladores!

Hoy publico este breve artículo para todos aquellos que quieran añadirse una placa muy chula (shield) de Open Exchange como esta:

 En tu repositorio de GitHub puedes incluirla añadiendo una simple línea:

[![Gitter](https://img.shields.io/badge/Available%20on-Intersystems%20Open%20Exchange-00b2a9.svg)](https://openexchange.intersystems.com/package/csvgen)

Recuerda escribir en la URL la ruta a tu página en Open Exchange.

Gracias a los participantes del concurso por esta placa tan chula :D

¿Qué otros shields o placas útiles conoces? ¡Compártelos en los comentarios!

0
0 113
Artículo Alberto Fuentes · mayo 19, 2021 1m read

En Studio, podías abrir una clase directamente usando su nombre, sin tener que recorrer completamente el árbol de paquetes con un montón de clics hasta llegar a la clase deseada.

Con Ctrl + O o (File -> Open) podías escribir el nombre de la clase de forma sencilla, por ejemplo:

Pulsabas Enter y voilà!, la clase se abría.

¿Cómo se logra esto en VSCode?

0
0 1023
Artículo Alberto Fuentes · mayo 14, 2021 2m read

Si trabajas utilizando el Portal de Gestión con varias instancias de IRIS, es posible que te resulte útil establecer el Modo del Sistema de esas instancias, de forma que tengas un recordatorio visual acerca del tipo de instancia con la que estás trabajando.

Por ejemplo: image

or:

or:

or:

Esta configuración se establece aquí:

Y la funcionalidad se menciona aquí en la documentación.

Internamente esta configuración se almacena en la global ^%SYS("SystemMode") y tiene como posibles valores: LIVE, TEST, DEVELOPMENT, FAILOVER.

Puede obtenerse este valor también utilizando $SYSTEM.Version.SystemMode()

0
0 128
Artículo Alberto Fuentes · mayo 6, 2021 4m read

¡Hola desarrolladores!

Supón que tienes una clase persistente con datos y quieres tener una interfaz de usuario Angular sencilla, para ver los datos y llevar a cabo operaciones CRUD.

En este artículo describíamos cómo desarrollar una interfaz de usuario Angular para InterSystems IRIS utilizando RESTForms2.

A continuación vamos a explicar cómo conseguir una interfaz de usuario Angular sencilla que permita realizar operaciones CRUD y ver automáticamente los datos de tu clase de InterSystems IRIS en menos de 5 minutos.

¡Vamos!

1
0 350
Artículo Alberto Fuentes · abr 28, 2021 8m read

Introducción

Si resuelves problemas complejos en ObjectScript, probablemente tienes mucho código que funciona con los valores de %Status. Si has interactuado con clases persistentes desde una perspectiva de objetos (%Save, %OpenId, etc.), casi seguro que las ha visto. 

Un %Status proporciona una envoltura alrededor de un mensaje de error localizable en las plataformas de InterSystems. Un estado OK ($$$OK) simplemente es igual a 1, mientras que un mal estado ($$$ERROR(errorcode,arguments...)) se representa como un 0 seguido de un espacio seguido de una lista $ListBuild con información estructurada sobre el error.

1
1 237
Artículo Alberto Fuentes · abr 22, 2021 1m read

¡Hola! ¿Sabéis que se puede habilitar Ctrl+C y Ctrl+V en el terminal de IRIS para Windows?

Para hacerlo, hay que abrir el Terminal, seleccionar Edit > User Settings y habilitar Widows Edit accelerators.

Esta opción especifica si el Terminal habilita atajos de teclado habituales en Windows (Ctrl+C, Ctrl+V, Ctrl+Shift+V) además de los atajos típicos del Terminal básico (Ctrl+Insert, Shift+Insert).

Tras habilitar esa opción Ctrl+C y Ctrl+V deberían estar habilitados y funcionar correctamente.

1
0 130
Artículo Alberto Fuentes · abr 15, 2021 4m read

Hola a todos! Comentamos hoy una entrada de Timothy Leavitt cuyo equipo (Application Services en InterSystems - encargado de desarrollar y mantener muchas de nuestras aplicaciones internas, y proporcionar herramientas y prácticas recomendadas a otras aplicaciones departamentales), durante el último año, se embarcó en un viaje hacia el desarrollo de interfaces de usuario basadas en Angular/REST, para las aplicaciones existentes construidas originalmente con CSP y/o Zen.

2
0 235
Artículo Alberto Fuentes · mar 16, 2021 1m read

Hola! Comparto hoy un ejemplo de Yuri Marx sobre el uso de ReadMIMEPart. Si necesitáis obtener un fichero de una API o formulario multipart echadle un ojo a este ejemplo:

Class dc.Test.TestService Extends Ens.BusinessService

{

 
Parameter ADAPTER = "EnsLib.HTTP.InboundAdapter";

 
Method OnProcessInput(pInput As %GlobalBinaryStream, pOutput As %RegisteredObject) As %Status

{

    Set file=##class(%Stream.FileBinary).%New()

    Set file.Filename="/tmp/automl11.png"

    Set reader = ##class(%Net.MIMEReader).%New()

    //Set message = ##class(%Net.MIMEPart).%New()

    Do reader.OpenStream(pInput)

    Set tsc2 = reader.ReadMIMEMessage(.message)

    Do message.ClearHeaders()

    Do file.CopyFromAndSave(message.Body) 

    

    Set tSC=$$$OK

    Set pOutput = "success" 

    Quit tSC

}

 
}
0
0 113
Artículo Alberto Fuentes · mar 12, 2021 12m read

Una cuestión muy común es cuál es la configuración ideal para el servidor web Apache HTTPD cuando se utiliza con HealthShare. El propósito de este artículo es describir la configuración inicial recomendada del servidor web para cualquier producto HealthShare. 

Como punto de partida, se recomienda la versión 2.4.x (64-bit) de Apache HTTPD. Existen versiones anteriores como la 2.2.x, pero no se recomienda esta versión por rendimiento y escalabilidad de HealthShare.

0
0 4502
Artículo Alberto Fuentes · mar 2, 2021 1m read

Si os habéis pasado de Studio a VSCode recientemente tal vez os hayáis dado cuenta de que en el Explorador faltan algunos elementos. Por ejemplo, cuando se crea una API REST a partir de sus especificaciones, se generan 3 clases: .impl, .disp y .spec, sin embargo la clase no se muestra por defecto en el Explorador.

Como la clase es una clase generada, para mostrarla tendremos que activar la opción correspondiente haciendo click en en el Explorador:

En ese mismo lugar también encontraremos una opción para mostrar los elementos de sistema.

0
0 106
Artículo Alberto Fuentes · feb 23, 2021 2m read

Hola a todos! Os comparto hoy un artículo sobre la utilización del procesamiento de lenguaje natural y su combinación con FHIR donde se muestra un chatbot que interactúa con FHIR desarrollado por Renato Banzai.

¿Qué significa PLN?

PLN significa Procesamiento del Lenguaje Natural (NLP en inglés) y es un campo de la Inteligencia Artificial muy complejo que utiliza técnicas para, en pocas palabras, “entender de qué se está hablando”.

¿Y qué es FHIR?

0
0 219
Artículo Alberto Fuentes · feb 17, 2021 1m read

Hola de nuevo a todos!

Cuando hacemos una instalación por defecto de VS Code, nos podemos encontrar que al crear un nuevo archivo, el lenguaje que tiene cargado por defecto es "Plain Text":

Debemos hacer click ahí para cambiar el lenguaje cargado para el archivo.

Por suerte, hay una configuración del VS Code que podemos utilizar para ajustar este comportamiento, se llama files.defaultLanguage. Aquí podemos indicar el ID del lenguaje que queramos o incluso podemos configurarlo para que utilice el mismo lenguaje que tenemos cargado en el contexto en el que estamos trabajando actualmente:

"files.defaultLanguage": "${activeEditorLanguage}"
0
0 205
Artículo Alberto Fuentes · feb 11, 2021 1m read

Hola a todos,

Compartimos hoy un truco que quizá le resulte útil a aquellos que tienen que trabajar con JavaScript embebido.

Si tienes que trabajar con CSP o Zen probablemente más de una vez has necesitado utilizar JavaScript embebido. Supón que tienes que programar algunos bucles, que utilizan los caracteres <` o `> en alguna expresión, por ejemplo:

&js< 
               var test = document.getElementById('seTest');
               for (var i = 0; i < test.options.length; i++) {

                              // hacer algo con test.options[i]...
               }             

>
0
0 166
Artículo Alberto Fuentes · ene 28, 2021 2m read

Hola a todos! 

Comparto una pequeña utilidad (servicio REST) para descargar mensajes de una producción de interoperabilidad como ficheros.

Sólo necesitas:

  1. Crear una aplicación web en el Portal de Gestión (e.g. /downloadmsg) que tenga configurado DispatchClass=Util.DownloadMsg.
  2. Llamar a la utilidad pasándole el namespace y el identificador de cabecera del mensaje a descargar. http://localhost:52773/downloadmsg/ns/dev/msgid/17441
/// 
/// Util to download messages given a message header id
/// 
/// Setup:
/// 1. Create a webapplication (e.g. /downloadmsg) and set DispatchClass=Util.DownloadMsg
/// 2. Go to http://localhost:52773/downloadmsg/ns/user/msgid/19 to download the message reference by header 19
Class Util.DownloadMsg Extends %CSP.REST
{

XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
    <Route Url="/ns/:ns/msgid/:msgId" Method="GET" Call="DownloadMessage"/>
</Routes>
}

/// Download a message given a Ens.MessageHeader id
ClassMethod DownloadMessage(ns As %String, msgId As %String = "") As %Status
{
    set ret = $$$OK
    set currentNs = $namespace

    try {
        set $namespace = ns
        $$$ThrowOnError(..ExportMsgToStream(msgId, .stream, .filename))

        // set headers to download stream as filename
        do %response.SetHeader("Content-Type", "application/octet-stream")
        do %response.SetHeader("Content-Disposition", "attachment; filename="""_filename_"""")
        do %response.SetHeader("Content-Length", stream.Size)
        do stream.Rewind()
        do stream.OutputToDevice()

    } catch ex {
        set ret = ex.AsStatus()
    }

    // restore namespace
    set $namespace = currentNs

    quit ret
}

/// Export a message to stream given a Ens.MessageHeader id
ClassMethod ExportMsgToStream(msgId As %String, Output stream As %Stream.Object, Output filename As %String) As %Status
{
    set ret = $$$OK
    try {
        // stream
        set stream = ##class(%Stream.GlobalCharacter).%New()
        set filename = ""

        // message header
        set headerObj = ##class(Ens.MessageHeader).%OpenId(msgId,,.sc)
        $$$ThrowOnError(sc)

        // message body
        set obj = $classmethod(headerObj.MessageBodyClassName, "%OpenId", headerObj.MessageBodyId)
        set classname = $classname(obj) 

        // output to stream
		if classname="EnsLib.HL7.Message" {
			set sc = $method(obj, "OutputToLibraryStream", .stream)
			$$$ThrowOnError(sc)
			set filename = msgId_".hl7"
		}
		else {
			set writer = ##class(%XML.Writer).%New()
			set writer.Indent=1
			set writer.NoXMLDeclaration=1
			$$$ThrowOnError(writer.OutputToStream(.stream))
			$$$ThrowOnError(writer.RootObject(obj))
			set filename = msgId_".xml"
		}
    } catch ex {
        set ret = ex.AsStatus()
    }
    quit ret
}

}
2
0 209