Pesquisar

Artigo
· Jun. 7, 2024 7min de leitura

Flujos de tareas con InterSystems IRIS Workflow Engine - Conexión con aplicaciones externas

Finalmente y con un poco de retraso, concluimos esta serie de artículos sobre nuestro Workflow Engine mostrando un ejemplo de la conexión que podríamos hacer desde una aplicación para móvil.

En el artículo anterior mostrábamos el ejemplo que íbamos a tratar, una aplicación que permita realizar un control pormenorizado de una patología crónica como puede ser la hipertensión tanto al paciente como a su médico asociado. En este ejemplo el paciente dispondrá de acceso desde su móvil a una aplicación web (básicamente, una página web diseñada para ser responsive con el dispositivo) en la que recibirá notificaciones en base a las lecturas que el tensiómetro portatil remita a la instancia de IRIS.

Por lo tanto tendremos dos accesos diferentes a nuestra instancia de IRIS:

  • Acceso del usuario desde aplicación móvil.
  • Acceso del dispositivo para remitir las lecturas de tensión arterial.

En este artículo veremos la primera de ellas que permite al paciente gestionar las tareas que sus lecturas vayan generando.

Conexión aplicación móvil - IRIS

Para esta conexión lo más sencillo es configurar una aplicación web dentro de IRIS y para ello accederemos desde el portal de gestión, System Administration -> Security -> Applications -> Web Applications:

A continuación en la lista que se nos muestra pulsaremos Create new application que nos abrirá una pantalla como la siguiente:

En esta pantalla configuremos los siguientes campos:

  • Name: en el que definiremos la URL que publicaremos  para dar acceso a nuestra funcionalidad desplegada en IRIS.
  • Namespace: el namespace al que queremos que esté asociada la aplicación web, esto nos permitirá posteriormente aprovechar las funcionalidades de las producciones de interoperabilidad.
  • REST: seleccionaremos esta opción ya que lo que vamos a publicar es una API de REST para permitir conexiones HTTP.
  • Dispatch Class: clase de ObjectScript que recibirá la llamada HTTP y decidirá que hacer con la misma.
  • Use JWT Authentication: marcando esta opción se nos habilitarán sobre la URL que hemos definido para nuestra aplicación los endpoint /login /logout que nos permitirá obtener un JSON Web Token para autentificar nuestras llamadas sobre IRIS.
  • Security Settings -> Allowed Authentication Methods: que marcaremos a password para securizar nuestras llamadas.

Echemos un vistazo a nuestra clase Workflow.WS.Service:

Class Workflow.WS.Service Extends %CSP.REST
{

Parameter HandleCorsRequest = 0;
Parameter CHARSET = "utf-8";
XData UrlMap [ XMLNamespace = "https://www.intersystems.com/urlmap" ]
{
<Routes>
	<Route Url="/getTasks" Method="GET" Call="GetTasks" />
    <Route Url="/saveTask" Method="POST" Call="SaveTask" />
</Routes>
}

ClassMethod OnHandleCorsRequest(url As %String) As %Status
{
	set url = %request.GetCgiEnv("HTTP_REFERER")
    set origin = $p(url,"/",1,3) // origin = "http(s)://origin.com:port"
    // here you can check specific origins
    // otherway, it will allow all origins (useful while developing only)
	do %response.SetHeader("Access-Control-Allow-Credentials","true")
	do %response.SetHeader("Access-Control-Allow-Methods","GET,POST,PUT,DELETE,OPTIONS")
	do %response.SetHeader("Access-Control-Allow-Origin",origin)
	do %response.SetHeader("Access-Control-Allow-Headers","Access-Control-Allow-Origin, Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control")
	quit $$$OK
}

ClassMethod GetTasks() As %Status
{
    Try {
        Do ##class(%REST.Impl).%SetContentType("application/json")
        If '##class(%REST.Impl).%CheckAccepts("application/json") Do ##class(%REST.Impl).%ReportRESTError(..#HTTP406NOTACCEPTABLE,$$$ERROR($$$RESTBadAccepts)) Quit
        Do ##class(%REST.Impl).%SetStatusCode("200")
        set sql = "SELECT %Actions, %Message, %Priority, %Subject, TaskStatus_TimeCreated, ID FROM EnsLib_Workflow.TaskResponse WHERE TaskStatus_AssignedTo = ? AND TaskStatus_IsComplete = 0"
        set statement = ##class(%SQL.Statement).%New(), statement.%ObjectSelectMode = 1
        set status = statement.%Prepare(sql)
        if ($$$ISOK(status)) {
            set resultSet = statement.%Execute($USERNAME)
            if (resultSet.%SQLCODE = 0) {
                set tasks = []
                while (resultSet.%Next() '= 0) {
                    set task = {"actions": "", "message": "", "priority": "", "subject": "", "creation": "", "id": ""}
                    set task.actions = resultSet.%GetData(1)
                    set task.message = resultSet.%GetData(2)
                    set task.priority = resultSet.%GetData(3)
                    set task.subject = resultSet.%GetData(4)
                    set task.creation = resultSet.%GetData(5)
                    set task.id = resultSet.%GetData(6)
                    do tasks.%Push(task)
                }                
            }
        }
        set result = {"username": ""}
        set result.username = $USERNAME
        Do ##class(%REST.Impl).%WriteResponse(tasks)
        
    } Catch (ex) {
        Do ##class(%REST.Impl).%SetStatusCode("400")
        return ex.DisplayString()
    }

    Quit $$$OK
}

ClassMethod SaveTask() As %Status
{
    Try {
        Do ##class(%REST.Impl).%SetContentType("application/json")
        If '##class(%REST.Impl).%CheckAccepts("application/json") Do ##class(%REST.Impl).%ReportRESTError(..#HTTP406NOTACCEPTABLE,$$$ERROR($$$RESTBadAccepts)) Quit
        // Reading the body of the http call with the person data
        set dynamicBody = {}.%FromJSON(%request.Content)
        
        set task = ##class(EnsLib.Workflow.TaskResponse).%OpenId(dynamicBody.%Get("id"))
        set sc = task.CompleteTask(dynamicBody.action)

        if $$$ISOK(sc) {	        
            Do ##class(%REST.Impl).%SetStatusCode("200")
            Do ##class(%REST.Impl).%WriteResponse({"result": "success"})         
		}	
        
    } Catch (ex) {
        Do ##class(%REST.Impl).%SetStatusCode("400")
        Do ##class(%REST.Impl).%WriteResponse({"result": "error"})
    }

    Quit $$$OK
}

}

Como podéis observar, desde nuestro WS resolvemos toda la lógica que necesitamos pero no os recomiendo hacer esto, ya que perdemos la trazabilidad que podríamos conseguir enviando las peticiones recibidas a la producción configurada en el Namespace.

Echando un vistazo a la sección de URLMap veremos que tenemos 2 endpoints configurados en nuestro WS:

  • getTasks: para recuperar todas las tareas pendientes del usuario (si veis la SQL utilizada estamos pasando el nombre de usuario directamente de la variable generada al loguearse).
  • saveTask: en las que recibiremos la respuesta del usuario a la tarea y procederemos a finalizarla ejecutando el método CompleteTaks de la clase EnsLib.Workflow.TaskResponse.

Por parte de IRIS ya estaría todo configurado para que la aplicación externa se conecte.

Probando la aplicación externa con el Workflow Engine

Primeramente simularemos el envío de un mensaje de HL7 a nuestra producción copiando el fichero /shared/hl7/message_1_1.hl7 a la ruta /shared/in, veamos el mensaje que estamos enviando:

MSH|^~\&|HIS|HULP|EMPI||20240402111716||ADT^A08|346831|P|2.5.1
EVN|A08|20240402111716
PID|||07751332X^^^MI^NI~900263^^^HULP^PI||LÓPEZ CABEZUELA^ÁLVARO^^^||19560121|F|||PASEO MARIO FERNÁNDEZ 258 1 DERECHA^^MADRID^MADRID^28627^SPAIN||555819817^PRN^^ALVARO.LOPEZ@VODAFONE.COM|||||||||||||||||N|
PV1||N
OBX|1|NM|162986007^Pulso^SNM||72|^bpm|||||F|||20240402111716
OBX|2|NM|105723007^Temperatura^SNM||37|^Celsius|||||F|||20240402111716
OBX|3|NM|163030003^Presión sanguínea sistólica^SNM||142|^mmHg|||||F|||20240402111716
OBX|4|NM|163031004^Presión sanguínea diastólica^SNM||83|^mmHg|||||F|||20240402111716

Para los que no recordéis los anteriores artículos, habíamos definido en nuestro BPL que se generase una alerta cuando la presión sistólica superase los 140 o la diastólica los 90, por lo tanto, este mensaje deberá generar una tarea de aviso para nuestro paciente con DNI 07751332X y otra automática que se mantendrá abierta hasta que IRIS reciba la nueva notificación.

Veamos nuestra aplicación móvil:

Ahí tenemos 2 tareas generadas, la primera de ellas que hemos definida como manual y que depende del usuario para su finalización y la segunda que hemos declarado como automática y que para que desaparezca el usuario deberá realizar una nueva lectura con su tensiómetro. Si echamos un vistazo a la llamada HTTP podremos ver como hemos incluido el JWT en la misma :

Si el usuario pulsa en el botón Accept de la tarea pendiente el flujo se mantendrá a la espera de recibir la lectura del tensiómetro y no avanzará a los siguiente pasos. Una vez aceptada la tarea manual y recibida una nueva lectura del tensiómetro en la que nuevamente se superan los límites marcados el sistema generará dos nuevas tareas de aviso, una para el paciente y otra para el médico asociado en el que se advierte de una posible crisis:

¡Perfecto! Ya tenemos montado nuestro sistema de avisos para los pacientes de una forma sencilla y rápida.

Conclusión

Como habéis podido ir viendo en esta serie de artículos la funcionalidad del Workflow Engine junto con las capacidades de interoperabilidad de InterSystems IRIS proveen de una potencialidad increible para la implementación de procesos de negocio que pocas otras soluciones empresariales pueden aportar. Es cierto que quizás sea necesario conocimientos técnicos para sacarle todo el jugo pero realmente merece la pena el esfuerzo requerido.

Discussão (0)1
Entre ou crie uma conta para continuar
InterSystems Oficial
· Jun. 7, 2024

¿Qué hay de nuevo en InterSystems Language Server 2.5.0? - Repost

Nota: esto fue publicado originalmente el 5 de junio de 2024, pero se presentó como si hubiera sido publicado el 9 de mayo de 2024, por lo que este repost corrige la fecha.

Las actualizaciones recientes del InterSystems Language Server introducen muchas mejoras significativas destinadas a mejorar la experiencia y la productividad del desarrollador. Aquí hablaré de algunas de las más importantes, mientras que la lista completa, que incluye numerosas correcciones de errores, se puede encontrar en el CHANGELOG del Language Server.

Descripciones detalladas para errores de sintaxis

En el pasado, todos los errores de sintaxis se informaban simplemente como "Error de sintaxis". Ahora, el error de sintaxis informado en el panel PROBLEMS de VS Code tiene el mismo detalle que encuentras al compilar en el terminal, ayudándote a identificar y resolver problemas en tu código más rápidamente. En la captura de pantalla a continuación, tengo varios errores en mi código ObjectScript. A la izquierda, en Before (antes), el servidor de lenguajes solo informaba "Error de sintaxis". Ahora, en After (después), verás que el servidor de lenguajes puede proporcionar descripciones de errores mucho más útiles en el panel PROBLEMS. Y recuerda, todo esto sucede mientras escribes, antes de la compilación. Así que es una buena idea mantener este panel visible si le soleis sacar partido a este tipo de ayudas.

Aquí podemos ver el antes (before) y después (after). 

Advertencias para palabras reservadas de SQL en clases persistentes

Ya sabéis que no debéis intentar usar palabras reservadas de SQL en nombres de clases o propiedades. Pero en caso de que lo olvidéis, o uséis una menos habitual, como LEVEL, por error, el analizador ahora os advertirá incluso antes de intentar la compilación. En la captura de pantalla a continuación, he nombrado una propiedad "unique". Esa es una palabra reservada en SQL, por lo que aparece subrayada con una advertencia y, al pasar el cursor sobre el texto subrayado, se muestra un mensaje apropiado.

Descripción emergente de la clase al pasar el cursor sobre una variable escrita

Al pasar el cursor sobre una variable, ahora veréis instantáneamente la clase que representa junto con la descripción de la clase. En la captura de pantalla a continuación, estoy pasando el cursor sobre la variable `task` en la línea 142 (de Tester.cls en el panel izquierdo). Obtengo el nombre completo de la clase seguido de la descripción proporcionada por el autor de la clase. En el panel derecho estoy mostrando la fuente de rs.pipeline.Task para que podáis ver de dónde proviene esa información.

Seguimiento de variables en procedure blocks

Si escribís rutinas, ahora recibiréis advertencias sobre variables potencialmente indefinidas en procedure blocks, al igual que desde hace tiempo ocurre con los métodos de clase. ¡Esto es muy útil para prevenir posibles errores en tiempo de ejecución que a menudo son difíciles de identificar!

 

Otras actualizaciones documentan las últimas características de IRIS, incluidas las funciones vectoriales, y añaden documentación más completa y funciones de ayuda dentro del editor. Los desarrolladores ahora pueden acceder a información detallada y ejemplos directamente dentro de su entorno de codificación, reduciendo la necesidad de cambiar de contexto y buscar recursos externos.

Estas nuevas características tienen como objetivo simplificar el proceso de codificación, reducir errores y mejorar la productividad general de los desarrolladores que usan el InterSystems Language Server. Una vez más, para obtener una lista detallada de todos los cambios y mejoras, podéis consultar el changelog completo en GitHub.

Discussão (0)1
Entre ou crie uma conta para continuar
Anúncio
· Jun. 7, 2024

[Vidéo] Mise à l'échelle du volume d'utilisateurs et de données dans InterSystems IRIS

Salut la Communauté!

Profitez de regarder la nouvelle vidéo sur la chaîne Youtube d'InterSystems France

📺 Mise à l'échelle du volume d'utilisateurs et de données dans InterSystems IRIS

Votre plate-forme de données doit soutenir votre entreprise à mesure que vous développez vos données et votre utilisation. Regardez la vidéo pour découvrir comment le logiciel InterSystems permet une mise à l'échelle horizontale et verticale.

Cette vidéo est doublée grâce à Bard, l'intelligence artificielle de Google. 

N'oubliez pas à partager vos réflexions et impressions dans des commentaires après avoir regardé cette vidéo !

Discussão (0)1
Entre ou crie uma conta para continuar
Discussão (4)1
Entre ou crie uma conta para continuar
Resumo
· Jun. 6, 2024

Join our new Ideas Contest!

Dear Community Member!

We're super excited to invite you to participate in our next contest!

💡 The 3rd InterSystems Ideas Contest 💡

We're looking for your innovative ideas to enhance InterSystems IRIS and related products and services. We encourage suggestions based on real-life use cases, highlighting the tangible benefits your idea will bring to other users and how it will enhance developers' experiences with InterSystems technology.

📅 Duration: June 10 - July 7, 2024

🏆 Prizes for the best ideas!

🎁 Gifts for everyone: A special gift will be given to each author whose idea is accepted in the contest.

>> Full contest details here.

We're looking forward to your entries 😉