Limpiar filtro
Artículo
Alberto Fuentes · 20 ene, 2023
La funcionalidad IntegratedML de InterSystems IRIS se utiliza para obtener predicciones y probabilidades mediante el uso de la técnica AutoML. AutoML es una tecnología de Machine Learning utilizada para seleccionar el mejor algoritmo/modelo de Machine Learning para predecir el estado, los números y los resultados generales basados en los datos pasados (datos utilizados para entrenar el modelo AutoML). No necesitas un científico de datos, porque AutoML probará los algoritmos de Machine Learning más comunes y seleccionará el mejor algoritmo para ti, basado en las características de los datos analizados.
InterSystems IRIS incorpora un motor AutoML, pero también permite utilizar H2O y DataRobot. En este artículo mostraré los pasos para utilizar el motor AutoML de InterSystems.
Paso 1 - Descargar la aplicación de muestra para hacer los ejercicios
1. Ve a https://openexchange.intersystems.com/package/Health-Dataset
2. Clonar/git pull el repositorio en cualquier directorio local
$ git clone https://github.com/yurimarx/automl-heart.git
3. Abrir un terminal de Docker en este directorio y ejecutar:
$ docker-compose build
4. Ejecutar el contenedor de IRIS:
$ docker-compose up -d
Paso 2 - Comprender el escenario y los datos
El escenario consiste en predecir, a partir de datos previos, las enfermedades cardíacas. Los datos disponibles para hacerlo, son:
SELECT age, bp, chestPainType, cholesterol, ekgResults,
exerciseAngina, fbsOver120, heartDisease, maxHr,
numberOfVesselsFluro, sex, slopeOfSt, stDepression, thallium
FROM dc_data_health.HeartDisease
El diccionario de datos de la tabla HeartDisease es (fuente: https://data.world/informatics-edu/heart-disease-prediction/workspace/data-dictionary):
Nombre de la columna
Tipo
Descripción
age
Número entero
En años
sex
Número entero
(1 = hombre; 0 = mujer)
chestPainType
Número entero
Valor 1: Angina típica -- Valor 2: Angina atípica -- Valor 3: Sin dolor de angina -- Valor 4: Asintomático
bp
Número entero
Presión arterial en reposo (en mm Hg al ingresar en el hospital)
cholesterol
Número entero
Colesterol sérico en mg/dl
fbsOver120
Número entero
(glucosa en sangre en ayunas > 120 mg/dl) (1 = verdadero, 0 = falso)
ekgResults
Número entero
Resultados del electrocardiograma de reposo -- Valor 0: normal -- Valor 1: con anormalidad en la onda ST-T (inversiones de la onda T y/o elevación o depresión del ST de > 0,05 mV) -- Valor 2: que muestra hipertrofia ventricular izquierda probable o definida
maxHr
Número entero
Frecuencia cardíaca máxima alcanzada
exerciseAngina
Número entero
Angina inducida por el ejercicio (1 = sí, 0 = no)
stDepression
Doble
Descenso del segmento ST inducida por el ejercicio relacionado al reposo
slopeOfSt
Número entero
La pendiente del segmento ST para el ejercicio máximo -- Valor 1: pendiente ascendente -- Valor 2: plano -- Valor 3: pendiente descendente
numberOfVesselsFluro
Número entero
Número de vasos mayores (de 0 a 3) coloreados por la fluoroscopia
thallium
Número entero
3 = normal, 6 = defecto fijo, 7 = defecto reversible
heartDisease
Cadena
Valor 0: < 50% de estrechamiento del diámetro -- Valor 1: > 50% de estrechamiento del diámetro
heartDisease es la propiedad que tenemos que predecir.
Paso 3 - Preparar los datos para el entrenamiento
La tabla HeartDisease tiene 270 filas. Tomaremos 250 para entrenar nuestro modelo de predicción. Para ello, crearemos la siguiente vista dentro del Portal de administración > Explorador de sistemas > SQL:
CREATE VIEW automl.HeartDiseaseTrainData AS
SELECT * FROM dc_data_health.HeartDisease WHERE ID < 251
Paso 4 - Preparar los datos para la validación
Tomaremos 20 filas para validar los resultados de la predicción. Para ello, crearemos la siguiente vista dentro del Portal de administración > Explorador de sistemas > SQL:
CREATE VIEW automl.HeartDiseaseTestData AS
SELECT * FROM dc_data_health.HeartDisease WHERE ID > 250
Paso 5 - Crear el modelo de AutoML para predecir las enfermedades cardíacas
IntegratedML permite crear un modelo de AutoML para hacer predicciones y probabilidades (más información en ). Para ello, crearemos el siguiente modelo dentro de Portal de administración > Explorador de sistemas > SQL:
CREATE MODEL HeartDiseaseModel PREDICTING (heartDisease) FROM automl.HeartDiseaseTrainData
El modelo obtendrá los datos del entrenamiento (aprendizaje) de la vista automl.HeartDiseaseTrainData.
Paso 6 - Ejecutar el entrenamiento
Para hacer esto, ejecutaremos la siguiente instrucción de SQL dentro del Portal de administración > Explorador de sistemas > SQL:
TRAIN MODEL HeartDiseaseModel
Paso 7 - Validar el modelo de entrenamiento
Para validar el modelo que acabamos de entrenar, ejecutaremos la siguiente instrucción de SQL dentro del Portal de administración > Explorador de sistemas > SQL:
VALIDATE MODEL HeartDiseaseModel FROM automl.HeartDiseaseTestData
Validamos el HeartDiseaseModel utilizando datos de prueba extraídos de la vista automl.HeartDiseaseTestData.
Paso 8 - Obtener las métricas de validación
Para conocer las métricas de validación del proceso de validación, ejecutaremos la siguiente instrucción SQL dentro del Portal de administración > Explorador de sistemas > SQL:
SELECT * FROM INFORMATION_SCHEMA_ML_VALIDATION_METRICS
Para entender los resultados obtenidos, consulta: [https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GIML_VALIDATEMODEL.](https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GIML_VALIDATEMODEL) La documentación de InterSystems IRIS detalla lo siguiente a partir de los resultados de validación:
La salida de VALIDATE MODEL es un conjunto de métricas de validación que se puede ver en la tabla INFORMATION_SCHEMA_ML_VALIDATION_METRICS.
Para los modelos de regresión, se guardan las siguientes métricas:
Varianza
R cuadrado
Error cuadrático medio
Error cuadrático medio de la raíz
Para los modelos de clasificación, se guardan las siguientes métricas:
Precision — Se calcula dividiendo el número de positivos verdaderos por el número de positivos predichos (suma de positivos verdaderos y falsos positivos).
Recall — Se calcula dividiendo el número de positivos verdaderos por el número de positivos reales (suma de positivos verdaderos y falsos negativos).
F-Measure — Se calcula mediante la siguiente expresión: F = 2 * (precision * recall) / (precision + recall)
Accuracy — Se calcula dividiendo el número de verdaderos positivos y verdaderos negativos por el número total de filas (suma de verdaderos positivos, falsos positivos, verdaderos negativos y falsos negativos) en todo el conjunto de pruebas.
Paso 9 - Ejecutar las predicciones con el nuevo modelo de AutoML - ¡el último paso!
Para conocer las métricas de validación del proceso de validación, ejecutaremos la siguiente instrucción SQL dentro del Portal de administración > Explorador de sistemas > SQL:
SELECT *, PREDICT(HeartDiseaseModel ) AS heartDiseasePrediction FROM automl.HeartDiseaseTestData
Compara las columnas heartDisease (valor real) y heartDiseasePrediction (el valor de la predicción)
¡Espero que os resulte útil!
Hola Alberto,
he intentado seguir el paso a paso, pero ya en el punto 3 del paso 1 me ha fallado con el siguiente error:
Global buffer setting requires attention. Auto-selected 25% of total memory.Allocated 726MB shared memory: 495MB global buffers, 80MB routine buffersThis copy of InterSystems IRIS has been licensed for use exclusively by:Community License expired.Copyright (c) 1986-2021 by InterSystems CorporationAny other use is a violation of your license agreement
Error: Invalid Community Edition license, may have exceeded core limit. - Shutting down the system : $zu(56,2)= 0Starting IRIS
An error was detected during InterSystems IRIS startup.** Startup aborted **The command '/bin/sh -c iris start IRIS && iris session IRIS < /tmp/iris.script && iris stop IRIS quietly' returned a non-zero code: 1ERROR: Service 'iris' failed to build : Build failed
Saludos Hola José Manuel,
Creo que quizá la imagen que tiene el ejemplo tiene una versión de IRIS Community que ya ha caducado.
En el directorio donde lo hayas descargado, modifica el fichero `Dockerfile` ([al comienzo](https://github.com/yurimarx/automl-heart/blob/master/Dockerfile#L2)) y prueba a utilizar por ejemplo esta versión:
```
ARG IMAGE=intersystemsdc/irishealth-ml-community:2022.2.0.368.0-zpm
``` Hola Alberto,
He realizado el cambio que indicas y ahora si la imagen se ha levantado de manera correcta, muchas gracias. Pero los siguientes pasos son dentro del portal de administración y el portal me solicita las claves de acceso, he revisado dentro de los archivos pero no he encontrado alguna pista del usuario y password que debo utilizar.
Gracias por tu ayuda Hola José Manuel,
Prueba con usuario `superuser` y contraseña por defecto del sistema `SYS` Hola Alberto, muchas gracias.
Con esas claves he logrado entrar.
Artículo
Jose-Tomas Salvador · 17 mar, 2021
En el Centro de Soporte Internacional (WRC), con frecuencia los clientes plantean preguntas sobre la configuración de un nuevo Web Gateway, en el que el Portal de Administración se carga a medias, pero no muestra imágenes. En este artículo explicaré por qué se produce este error, así como la forma de solucionarlo. Mi explicación se centra en el Web Gateway que enlaza con las instancias de InterSystems IRIS, pero la misma explicación debería aplicar también a la CSP Gateway que enlaza con instancias de Caché.
El problema:
Acabas de instalar el Web Gateway en un servidor web independiente. Cuando vas a cargar el Portal de Administración, ves que no puede mostrar o cargar imágenes, así:
Por qué sucede esto:
El problema es que para cargar el Portal de Administración en su totalidad, InterSystems IRIS debe cargar una serie de archivos .js, .css y .png (archivos estáticos). Si estás viendo una página del Portal de administración como la de arriba, no dudes en abrir la applet de Herramientas para Desarrolladores de tu navegador, ir a la pestaña de Red, y confirmar que no se están sirviendo varios componentes de tipo .js, .css, y .png:
Cuando se instala inicialmente la la Web Gateway, configuramos los mapeos solo para las siguientes extensiones:
.csp .cls .zen .cxw
Estos son los tipos de extensiones de archivo que los clientes van a utilizar con más frecuencia para sus propias aplicaciones personalizadas, además de la extensión .cxw que se utiliza para mostrar el Portal de administración de la Web Gateway. Si quieres cargar los componentes adicionales del Portal de Administración, tendrás que registrar tipos de archivo adicionales para que sean servidos por el Web Gateway.
Cómo solucionar el problema:
Para que el Portal de Administración se muestre completamente, debes configurar la Web Gateway para que sirva tipos de archivos adicionales. En el caso de IIS, se pueden añadir mapeos individuales para las extensiones .js, .png, .css, etc., o se puede agregar un mapeo genérico (wildcard mapping). La documentación para el Registro de tipos de archivos adicionales para IIS se puede encontrar aquí: https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GCGI_win#GCGI_registering
Si estás ejecutando el Web Gateway sobre Apache en un sistema Unix/Linux, tienes un par de opciones. Puedes configurar esto añadiendo extensiones de archivo adicionales, como es el caso de IIS, o puedes añadir una directiva de localización CSP. Consulta esta documentación para obtener más detalles: https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GCGI_ux, en el "Registro de tipos de archivos adicionales con CSP"
Pregunta
Mathew Lambert · 16 jun, 2020
Me gustaría saber si hay alguna forma de tener un callback o similar para clases persistentes, que se ejecute siempre después de la operacion (ya sea que falle o que vaya bien)
%OnOpen se ejecuta antes de la accion y no hay callback de after.
%OnAfterDelete y %OnAfterSave se ejecutan solo después de una operación satisfactoria.
Hola Mathew,
Siempre se puede hacer una clase que herede de %Persistent y que exponga los métodos que quieras para guardar por ejemplo. Internamente allí puedes crear tu Callback y luego llamar al %Save.
Algo así como:
Class MiPersistente Extends %Persistent {
Method OnGuardar() {
}
Method Guardar() {
..OnGuardar()
..%Save()
}
}
Luego en lugar de heredar de %Persistent heredas de esta clase y sobre escribes el Callback.
No lo he probado pero es una alternativa a investigar
Gracias
Ya pero esto tiene dos problemas, el %Save es diferente para cada clase (es code generator) por llo que no es lo mismo hacer un save de mi clase que de esta "super", por otro lado, me gustaría evitar tener que modificar >17k llamadas a %Save Buscar/Reemplazar todo 17 mil veces... ¿qué puede salir mal? Como parece que no hay nada que pueda solucionar esto ahora mismo, vamos a hablar con InterSystems. Creo que puede ser interesante.
Anuncio
Esther Sanchez · 23 jul, 2021
¡Hola desarrolladores!
Hace poco hemos añadido la página de Miembros / Members en Open Exchange. Podéis encontrarla en el menú de la página de inicio, en About/Members.
En esta nueva página se pueden ver todos los miembros registrados en Open Exchange, ordenados por orden alfabético por defecto, y con la posibilidad de ordenarlos por diferentes columnas:
Número de Aplicaciones (Applications) que han publicado
Número de veces que sus aplicaciones se han guardado como "Favoritas" (Bookmarks)
Número de seguidores (Followers)
Su clasificación (Rating)
Número de concursos (Contests) en los que ha participado
Número de premios (Rewards) que ha conseguido
Y en la página de cada aplicación hemos añadido los premios que ha conseguido dicha aplicación en los concursos de programación:
Y ahora... ¡os toca adivinar! ¿Cuántos premios creéis que ha conseguido el Héroe de los Concursos de InterSystems?¿Y sabríais decir quién es ese Superhéroe?
Dejad vuestras respuestas en los comentarios y en la nueva página de miembros en Open Exchange podéis comprobar si habéis acertado o no 🙂 Han sido mas o menos 10 concursos... como mucho serán 10, pero como también se dan el premio de la comunidad... me la juego ... 15 tiene el "supercode" ¿Y quién es el "supercode"? Pues me he quedado corto... el "Supercode" ha ganado 17 veces... que crack Henrique Gonçalves Dias
Artículo
Nancy Martínez · 30 mayo, 2022
Estoy seguro de que os habéis encontrado esta situación:
Hay un bug en un sistema que no puedes reproducir por ti mismo localmente
Necesitas ejecutar unas pocas líneas en la instancia afectada
Tienes acceso completo al Portal de Gestión
Pero no hay terminal, ni consola, ni acceso con Studio, Atelier o VSCode
¿Cómo ejecutar tus pocas líneas para probar???
Entra en Portal de Gestión / Explorador / SQL= Ejecutar consulta
Ahora crea un Stored Procedure con cualquier código que necesites
No hay límite de complejidad. Yo simplemente hago uno sencillo con un resultado predecible.
CREATE PROCEDURE RUN.ISOS()
LANGUAGE OBJECTSCRIPT
{
For i=1:1:20 write i," > "
Write "<br>THANKS !"
}
Haz clic en EJECUTAR y observa un nuevo Procedimiento
Después, examina este Procedimiento reciente y ejecútalo
Otra ejecución lo activa
y este es el resultado
y como especialista bien educado, limpia tu entorno cuando acabes
DROP PROCEDURE RUN.ISOS
¡Espero que os resulte útil en algún momento!
Documentación
Este artículo ha sido etiquetado como "Mejores prácticas" ("Best practices").
Los artículos con la etiqueta "Mejores prácticas" incluyen recomendaciones sobre cómo desarrollar, probar, implementar y administrar mejor las soluciones de InterSystems.
Anuncio
Esther Sanchez · 24 jun, 2022
Como sabéis, hay una etiqueta llamada "Mejores Prácticas", que se utiliza para destacar artículos de la Comunidad de Desarrolladores que incluyen recomendaciones sobre cómo desarrollar, probar, implementar y administrar mejor las soluciones de InterSystems. Cada 1-2 semanas los expertos de la companía eligen un nuevo artículo.
Hasta ahora, solo tienen dicha etiqueta artículos originales en inglés o artículos en español traducidos al inglés. La buena noticia es que ya podéis proponer artículos en español para que sean evaluados, aunque no estén traducidos al inglés.
¿Cómo podéis proponer un artículo?
Tenéis que acceder a este reto en Global Masters y poner el enlace al artículo que queréis que sea evaluado para incluir la etiqueta "Mejores Prácticas". También tenéis que incluir un breve comentario que explique por qué habéis elegido ese artículo.
Notas:
Puede ser un artículo propio o de otra persona
Aseguraos de que el artículo no tenga ya la etiqueta "Mejores Prácticas"
Podéis proponer hasta 5 artículos en este reto
Y además... ¡obtendréis 25 puntos en Global Masters solo por completar el reto! 🎉
¡Animaos! Seguro que hay más de un artículo en español que merece llevar la etiqueta "Mejores Prácticas".
Anuncio
Esther Sanchez · 18 nov, 2022
¡Hola desarrolladores!
Fue un auténtico placer encontrarnos en persona en el 1er Encuentro de la Comunidad de Desarrolladores. ¡Y fue un honor ver la sala llena! Lo pasamos muy bien y aprendimos muchas cosas. ¡Y os echamos de menos a todos los que no pudisteis venir!
Muchísimas gracias a todos los que estuvisteis y especialmente a nuestros amigos de Roche Diagnostics y Arisnova por las presentaciones tan interesantes que hicieron.
Gracias también a @Anastasia.Dyubaylo y @Evgeny.Shvarov por acompañarnos.
¡Y enhorabuena a Mario del Pozo, por su premio en el Kahoot! 👏
¡Estamos deseando volver a veros!
Algunas fotos del evento ⬇️
Yo creo que en el Kahoot hubo hasta codazos!! La verdad es que estuvo genial poder compartir experiencias y sobre todo vernos después de casi 3 años... y las exposiciones super interesantes... personalmente me quedé con ganas de más... y los que exponían ya ni hablamos (David Cano y Carlos Fernández de Roche y Florencio López y Mario del Pozo por Arisnova)... yo creo que si no los paran aún seguían. Estuvo genial. A ver si repetimos. Gran encuentro, la verdad es que va muy bien ver ejemplos de como la gente utiliza la tecnología Intersystems y sobretodo de sectores diferentes, casi tendremos que hacer un summit paralelo solo para desarrolladores, lanzo la idea ;-)
Anuncio
David Reche · 27 mar, 2023
InterSystems anuncia la Versión de Mantenimiento (Maintenance Release, MR) 2018.1.8 de Caché, Ensemble y HSAP. Es una versión de mantenimiento con muchas actualizaciones en una gran variedad de áreas.
Caché y Ensemble
Los kits completos de instalación de producto se pueden descargar de la página de distribución de software del Centro de Soporte Internacional (WRC):
Caché
Ensemble
Para más información sobre las correcciones en esta versión, consultad las Notas de Cambios de la Versión. La documentación de Caché y Ensemble incluye dichas Notas, así como el documento de Plataformas Soportadas, la Referencia de Clase y una completo conjunto de guías, referencias, tutoriales y artículos.
El número de compilación de esta versión es 2018.1.8.766.0.
HSAP
Esta versión de HealthShare Health Connect (HSAP) se basa en tecnología core versión 2018.1.5.659.0 con el siguiente módulo HealthShare:
Core: 15.032.9077
Los kits completos de instalación de producto se pueden descargar de la página de distribución de software del Centro de Soporte Internacional (clic aquí).
El número de versión de los kits de HealthShare Health Connect para esta versión es 2018.1.8HS.9077.0.
--> Nota: usa el campo "Maint/Core Ver" en la parte superior de la tabla e introduce "2018.1.8" para ver todos los kits disponibles.
Pregunta
Yone Moreno · 9 mayo, 2023
Buenos días,
Antes que nada agradecer el tiempo de ustedes al leer, reflexionar y sobre todo responder y aclarar las dudas.
Tenemos una cuestión:
¿Cuál es la forma recomendada de convertir un Objeto de Ensemble a JSON?,
en concreto, para ser más preciso:
¿cuál es la manera idónea de transformar un Mensaje Response con cualquier tipo de Property: %String, %List of String, otros objetos de Ensemble (EsquemasDatos); a un GlobalCharacterStream que represente al JSON? a retornar a Sistema Origen, desde el Servicio.
Porque en el equipo, a lo que estamos acostumbrados en los Servicios REST es a emplear el:
set claseAux = ##class(%ZEN.Auxiliary.jsonProvider).%New()
[...]
set tSC = claseAux.%WriteJSONStreamFromObject(.pOutput,.objetoSalida,,,,"aeloqtuw")
Set pOutput=##class(%GlobalBinaryStream).%New()
set claseAux = ##class(%ZEN.Auxiliary.jsonProvider).%New()
//Sacamos el body
set body = pInput.Read()
//Lo convertimos a Mensaje
set tSC= claseAux.%ConvertJSONToObject(.body,"Mensajes.Request.miFormacion.LoginRequest",.objetoEntrada,1)
//Enviamos al Proceso
set tSC = ..SendRequestSync("miFormacionv01r00",objetoEntrada,.objetoSalida)
//Convertimos el OBJETO devuelto por el Proceso en JSON
#dim objetoSalida As Mensajes.Response.miFormacion.LoginResponse
set tSC = claseAux.%WriteJSONStreamFromObject(.pOutput,.objetoSalida,,,,"aeloqtuw")
//Enviamos el JSON con cabeceras
Do:$$$ISOK(tSC) pOutput.SetAttribute("Content-Type","application/json")
do pOutput.SetAttribute("Access-Control-Allow-Origin","*")
do pOutput.SetAttribute("Access-Control-Allow-Credentials","true")
do pOutput.SetAttribute("Access-Control-Allow-Methods","GET")
do pOutput.SetAttribute("Access-Control-Allow-Headers","request,Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers")
Quit tSC
Sin embargo ¿cuál es la manera recomendada por ustedes desde InterSystems para realizar esta conversión?
De nuevo; gracias por el tiempo de ustedes al leer, reflexionar y sobre todo responder y aclarar las dudas.
Un saludo. Hola Yone! Justamente han preguntado algo parecido en la comunidad en inglés, te copio el hilo:
https://community.intersystems.com/post/creating-json-objects-objectscript-objects Gracias Luis Ángel Pérez.
En el hilo, se explican 3 formas de convertir Objeto a JSON, ahora bien; ¿cuál de las 3 es la recomendada por Intersystems, la preferible y/o estándar y por qué?
Eduard Lebedyuk expone 2 alternativas:
1º Utilizar la clase "result set" para contener los resultados:
Para utilizar esta opción, se debe crear una clase que extienda de %RegisteredObject y %JSON.Adaptor que tenga propiedades para contar los resultados (count) y una lista de los mismos (results). Por ejemplo:
Class Test.JSONRS Extends (%RegisteredObject, %JSON.Adaptor)
{
Property count As %Integer;
Property results As list Of Book;
}
Luego, se puede convertir un objeto normal a un objeto dinámico y asignarlo a la propiedad results de la clase Test.JSONRS utilizando la función %ObjectToAET:
set dynObj = ##class(%ZEN.Auxiliary.altJSONProvider).%ObjectToAET(obj)
set resultSet = ##class(Test.JSONRS).%New()
set resultSet.count = <cantidad de resultados>
set resultSet.results = dynObj
set jsonString = resultSet.%ToJSON()
2º Utilizar un enfoque más simple:
En esta opción, se genera el JSON directamente utilizando la función %JSONExport para cada objeto y concatenando los resultados. Por ejemplo:
set jsonString = {"results": <cantidad de resultados>, "items": [
##class(%JSON.Adaptor).%JSONExport(obj1)_", "_##class(%JSON.Adaptor).%JSONExport(obj2)_", "_...]}
Este enfoque es más simple pero puede ser menos eficiente en términos de uso de memoria y tiempo de ejecución. Sin embargo, puede ser más adecuado para casos en los que se trabaja con un pequeño número de objetos.
Por otro lado, Muni Ganesh explica esta 3ª vía:
Emplear la función "%ToJSON()" para convertir el objeto "MainObj" a formato JSON y se imprime el resultado.
set array=[]
set obj = {}
set obj.title="For Whom the Bell Tolls"
set obj.author="Hemmingway"
do array.%Push(obj)
set obj = {}
set obj.title="The Invisible Man"
set obj.author="Ellison"
do array.%Push(obj)
set obj = {}
set obj.title="Tender is the Night"
set obj.author="Fitzgerald"
do array.%Push(obj)
set arraylen=0
set iter = array.%GetIterator()
while iter.%GetNext() {
set arraylen=$I(arraylen)
}
set MainObj={}
set MainObj.results=arraylen
set MainObj.items=array
w MainObj.%ToJSON()
----------------------------------------------------------------------------------------------------------------
Output:
{"results":3,"items":[{"title":"For Whom the Bell Tolls","author":"Hemmingway"},{"title":"The Invisible Man","author":"Ellison"},{"title":"Tender is the Night","author":"Fitzgerald"}]}
--------------------------------------------------------------------------------------------------------------------
Desarrollando una integración en el ámbito de la interoperabilidad sanitaria, en un Servicio REST ¿cuál es la forma aconsejada por ustedes en Intersystems para convertir Objeto a JSON?
¿Cuál de las 3 es la recomendada por Intersystems, la preferible y/o estándar y por qué?
Gracias, muchas gracias por leer y responder, un saludo. Personalmente siempre he usado la de %JSONExport para transformar el JSON de una llamada REST por su sencillez de uso, pero es más una opinión personal.
Anuncio
David Reche · 2 mar, 2020
Desde marzo de 2020, Microsoft planea lanzar una serie de actualizaciones de seguridad que harán que los servidores Active Directory (AD) de Windows rechacen vínculos de canales no cifrados. Para más detalles de los cambios en Active Directory, pueden consultar el aviso de seguridad de Microsoft: ADV190023.
Las instancias de todos los productos de InterSystems que utilizan LDAP con los servidores Windows AD para el acceso de usuarios, pueden verse afectadas si no están configuradas correctamente para usar TLS/SSL. No solo las instancias ejecutándose en los servidores de Windows pueden verse afectadas. El riesgo potencial existe tanto para instancias que realizan la autenticación LDAP directamente como a través del mecanismo de Autenticación Delegada.
En base a las pruebas de InterSystems usando servidores AD actualizados con las políticas de seguridad estándar, se recomienda configurar todas las conexiones LDAP AD para utilizar TLS/SSL antes de aplicar los pertinentes parches de Microsoft a los servidores AD. Consulten la nota al final de este aviso para obtener ayuda en la configuración.
Además, antes de actualizar cualquier servidor AD, se debe instalar el parche CVE-2017-8563de Microsoft en todos los servidores Windows que conectan con estos servidores AD. Si no, los servidores AD rechazarán las conexiones desde los servidores de Windows, incluso si usan TLS/SSL.
Para cualquier pregunta relacionada con este aviso, contacten por favor con el Centro de Soporte Internacional.
Nota sobre configuración:
Si estas usando configuraciones LDAP, selecciona el checkbox de Use TLS/SSL encryption for LDAP sessions, tal y como se describe en el capitulo “Using LDAP” de la Security Administration Guide.
Si usas la clase %SYS.LDAP, invoca el método StartTLSs(), tal y como se describe en la documentación Class Reference Documentation. Los métodos Init() y SetOption() son también relevantes.
Tanto las Configuraciones LDAP como la clase %SYS.LDAP deben disponer de todos los certificados necesarios para validar el servidor de AD utilizado en la negociación TLS, incluyendo el Certificado raiz de la Autoridad de Certificación y cualquier certificado intermedio. Contacta con tu administrador de Windows Active Directory para obtener una copia the los certificados requeridos. Instala los mismos según:
Para clientes Windows, en el almacén de certificados local del computador Windows local
Para clientes no-Windows, en un fichero accesible por la instancia en formato PEM. Si exportas el certificado desde Windows utilizando el Certificate Export Wizard, el formato correcto es el denominado "Base-64 encoded X.509".
para más información acerca de localización de certificados, mira el capitulo “Using LDAP” de la Security Administration Guide
Artículo
Ricardo Paiva · 9 jul, 2021
Hola todos,
Quiero compartir un sencillo y rápido método que puede usarse para habilitar ssl con un certificado auto-firmado en una instancia de desarrollo local de IRIS/HealthShare. Esto permite probar funciones específicas de https, como OAuth.
1. Instalar OpenSSL
Windows: https://slproweb.com/download/Win64OpenSSL_Light-1_1_1g.exe
Debian Linux: $ sudo apt-get -y install openssl
RHEL: $ sudo yum install openssl
2. Crear un par de certificados auto-firmados. En tu terminal (powershell, bash, zsh, etc.)
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout apache-selfsigned.key -out apache-selfsigned.crt
Nota: este comando anterior creará un certificado que durará un año.
3. Editar el servidor web privado para utilizar el nuevo par de certificados auto-firmados
En el directorio de instalación de tu instancia, edita tu configuración de pws <install-dir>/httpd/conf/httpd-local.conf. Añade la siguiente sección antes de las directivas "Incluir ...".
# Port to listen for secure traffic On. The default is 443
LoadModule ssl_module "modules/mod_ssl.so"
Listen 10443
# Listen Virtual Host Block to define the keys we should use for that port
# If you define a different port in the Listen directive, change that here as well
<VirtualHost *:10443>
# We need a servername, it has not effect but is required by apache
ServerName mysecureinstance
# Turn on SSL for this Virtual Host
SSLEngine on
#key files, replace these paths with the path you generated the keys from in step 2.
SSLCertificateFile "/path/to/apache-selfsigned.crt"
SSLCertificateKeyFile "/path/to/apache-selfsigned.key"
</VirtualHost>
Este es un ejemplo de mi archivo de configuración:
En ejecución:
Nota: InterSystems no soporta este tipo de configuración HTTPS y, si necesitas un producto de producción, debes seguir las instrucciones para instalar apache2/IIS/nginx de manera completa. Este artículo está etiquetado como "Mejores prácticas" ("Best practices")
(Los artículos con la etiqueta "Mejores prácticas" incluyen recomendaciones sobre cómo desarrollar, probar, implementar y administrar mejor las soluciones de InterSystems).
Artículo
Jose-Tomas Salvador · 1 mayo, 2020
Era el momento del InterSystems hackathon y nuestro equipo, Artem Viznyuk y Eduard Lebedyuk tenian una placa Arduino (one) y varios componentes (de sobra). Así que su curso de acción estaba marcado - como todos los aprendices de Arduino, decidieron construir una estación meteorológica. Voy a aprovechar este artículo para seguir sus pasos y hacer lo mismo que ellos hicieron en 2016, pero con la persistencia de datos en IRIS y la visualización en Business Intelligence (antiguo DeepSee)! (Digamos que además de hacer la traducción del artículo original, aprovecho y nos actualizamos todos ;-) )
Trabajar con dispositivos
InterSystems IRIS puede trabajar directamente con muchos tipos de dispositivos físicos y lógicos:
Terminal
TCP
Al Spooler
Impresoras
Cinta magnética
Puertos COM
y muchos otros
Puesto que Arduino utilizar el puerto COM para las comunicaciones, tenemos todo lo que necesitamos.Generalmente, trabajar con dispositivos puede dividirse en 5 pasos:
Comando OPEN para registrar el dispositivo con el proceso actual y acceder
Comando USE para hacer que sea el primario
Hacer algún trabajo. READ para recibir datos de un dispositivo, y WRITE para enviar datos
USE de nuevo para conmutar el dispositivo primario
Comando CLOSE para liberar el dispositivo
Bien, esa es la teoría, ¿cómo es en la práctica?
Un parpadeo desde InterSystems IRIS
Primeramente, construimos un dispositivo con Arduino que lee un número del puerto COM y enciende un led durante unos milisegundos.
Circuito:
C code (for Arduino)
/* Led.ino
* Receive data on a COM port
* Connect your led to ledPin
*/
// Pin, to connect your led
#define ledpin 8
// Received data buffer
String inString = "";
// Execute once at the beginning
void setup() {
Serial.begin(9600);
pinMode(ledpin, OUTPUT);
digitalWrite(ledpin, LOW);
}
// Execute indefinetly
void loop() {
// Get data from com
while (Serial.available() > 0) {
int inChar = Serial.read();
if (isDigit(inChar)) {
// one character at a time
// and append it to data buffer
inString += (char)inChar;
}
// Encounter new line
if (inChar == '\n') {
// Power on the led
digitalWrite(ledpin, HIGH);
// be aware: toInt() converts a string that starts with a number to number...
int time = inString.toInt();
delay(time);
digitalWrite(ledpin, LOW);
// Flush the buffer
inString = "";
}
}
}
Y por último un método en InterSystems IRIS que envía el string 1000\n (acabado en nueva línea) al puerto COM:
/// Send 1000\n to a com port
ClassMethod SendSerial()
{
// Pon el puerto que te haya asignado el sistema a tu Arduino
set port = "COM3"
open port:(:::" 0801n0":/BAUD=9600) // Open device
set old = $IO // Record current primary device
use port // Switch to com port
write $Char(10) // Send some test data
hang 1
write 1000 _ $Char(10) // Send 1000\n
use old // Back to old terminal
close port // Free the device
}
«0801n0» es una cadena con parámetros para acceder al puerto COM, tal y como se describe en la documentación (busca portstate cuando estés en la página). Y /BAUD=9600 es, por supuesto, la velocidad de conexión.
Si ejecutamos este método en un terminal:
do ##class(Arduino.Habr).SendSerial()
No devolverá nada, pero un led parpadeará por un segundo.
Recepción de datos
Ahora vamos a conectar un keypad a InterSystems IRIS y recibir datos de entrada. Esto podría utilizarse para autenticar a un usuario con autenticación delegada, implementando también la rutina ZAUTHENTICATE.mac.
Circuito:
C code
/* Keypadtest.ino *
* Uses Keypad library,
* Connect Keypad to Arduino pins
* as specified in rowPins[] and colPins[].
*
*/
// Repository:
// https://github.com/Chris--A/Keypad
#include <Keypad.h>
const byte ROWS = 4; // Four rows
const byte COLS = 4; // Three columns
// Map symbols to keys
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
// Connect keypad pins 1-8 (up-down) to Arduino pins 11-4: 1->11, 2->10, ... , 8->4
// Connect keypad ROW0, ROW1, ROW2 и ROW3 to this Arduino pins
byte rowPins[ROWS] = { 7, 6, 5, 4 };
// Connect keypad COL0, COL1 and COL2 to this Arduino pins
byte colPins[COLS] = { 8, 9, 10, 11 };
// Keypad initialization
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup() {
Serial.begin(9600);
}
void loop() {
char key = kpd.getKey(); // Receive key pressed
if(key)
{
switch (key)
{
case '#':
Serial.println();
default:
Serial.print(key);
}
}
}
Y aquí tenemos un método en InterSystems IRIS utilizado para recoger los datos desde un puerto COM, una línea cada vez:
/// Receive one line till we encounter line terminator from COM1
ClassMethod ReceiveOneLine() As %String
{
set port = "COM3"
set str=""
try {
open port:(:::" 0801n0":/BAUD=9600)
set old = $io
use port
read str // Read till we encounter line terminator
use old
close port
} catch ex {
close port
}
return str
}
Lo ejecutamos en un terminal:
write ##class(Arduino.Habr).ReceiveOneLine()
Y se quedará esperando recibiendo datos de entrada hasta que se presione # (que sería enviado como un terminador de línea), tras lo cual los datos introducidos se mostrarán en el terminal.
Esto era la I/O básica Arduino-IRIS, y ahora ya estamos preparados para construir nuestra propia estación meteorológica.
Estación Meteorológica
¡Finalmente estamos llegando a la estación meteorológica! Utilizamos un fotoresistor y un sensor de Humedad y Temperatura DHT11 para obtener los datos.
Circuito:
C code
/* Meteo.ino *
* Register humidity, temperature and light level
* And send them to a COM port
* Output sample: H=1.0;T=1.0;LL=1;
*/
// Photoresistor pin (analog)
int lightPin = 0;
// DHT-11 pin (digital)
int DHpin = 8;
// Array to store DHT-11 temporary data
byte dat[5];
void setup() {
Serial.begin(9600);
pinMode(DHpin,OUTPUT);
}
void loop() {
delay(1000); // measure everything once per second
int lightLevel = analogRead(lightPin); //Get brightness level
temp_hum(); // Get temperature and humidity into dat variable
// And output the result
Serial.print("H=");
Serial.print(dat[0], DEC);
Serial.print('.');
Serial.print(dat[1],DEC);
Serial.print(";T=");
Serial.print(dat[2], DEC);
Serial.print('.');
Serial.print(dat[3],DEC);
Serial.print(";LL=");
Serial.print(lightLevel);
Serial.println(";");
}
// Get DHT-11 data into dat
void temp_hum() {
digitalWrite(DHpin,LOW);
delay(30);
digitalWrite(DHpin,HIGH);
delayMicroseconds(40);
pinMode(DHpin,INPUT);
while(digitalRead(DHpin) == HIGH);
delayMicroseconds(80);
if(digitalRead(DHpin) == LOW);
delayMicroseconds(80);
for(int i=0;i<4;i++)
{
dat[i] = read_data();
}
pinMode(DHpin,OUTPUT);
digitalWrite(DHpin,HIGH);
}
// Get a chunk of data from DHT-11
byte read_data() {
byte data;
for(int i=0; i<8; i++)
{
if(digitalRead(DHpin) == LOW)
{
while(digitalRead(DHpin) == LOW);
delayMicroseconds(30);
if(digitalRead(DHpin) == HIGH)
{
data |= (1<<(7-i));
}
while(digitalRead(DHpin) == HIGH);
}
}
return data;
}
Una vez que hemos cargado este código en Arduino, va a comenzar a enviar datos desde el puerto COM con el siguiente formato:
H=34.0;T=24.0;LL=605;
Donde:
H — humedad (de 0 al 100 por ciento)
T — temperatura (grados Celsius)
LL — Luminosidad (de 0 a 1023)
Vamos a almacenar estos datos en InterSystems IRIS. Para eso, escribimos una nueva clase Arduino.Info:
Class Arduino.Info Extends %Persistent
{
/// Puerto COM asociado - cambialo según tu sistema
Parameter SerialPort As %String = "com3";
Property DateTime As %DateTime;
Property Temperature As %Double;
Property Humidity As %Double(MAXVAL = 100, MINVAL = 0);
Property Brightness As %Double(MAXVAL = 100, MINVAL = 0);
Property Volume As %Double(MAXVAL = 100, MINVAL = 0);
ClassMethod AddNew(Temperature = 0, Humidity = 0, Brightness = 0, Volume = 0)
{
set obj = ..%New()
set obj.DateTime=$ZDT($H,3,1)
set obj.Temperature=Temperature
set obj.Humidity=Humidity
set obj.Brightness=Brightness/1023*100
set obj.Volume=Volume
write $SYSTEM.Status.DisplayError(obj.%Save())
}
Despues, escribimos un método que recibirá los datos desde Arduino y los transformará en objetos de tipo Arduino.Info:
/// Receive a RAW data in this format: H=34.0;T=24.0;LL=605;\n
/// Convert into Arduino.Info objects
ClassMethod ReceiveSerial(port = {..#SerialPort})
{
try {
open port:(:::" 0801n0":/BAUD=9600)
set old = $IO
use port
for {
read x //read one line
if (x '= "") {
set Humidity = $Piece($Piece(x,";",1),"=",2)
set Temperature = $Piece($Piece(x,";",2),"=",2)
set Brightness = $Piece($Piece(x,";",3),"=",2)
do ..AddNew(Temperature,Humidity,Brightness) // Add data
}
}
} catch anyError {
close port
}
}
Y finalmente conectamos Arduino y ejecutamos el método ReceiveSerial:
write ##class(Arduino.Info).ReceiveSerial()
Este método recibirá y almacenrá datos desde Arduino ininterrumpidamente.
Visualización de Datos
Tras construir nuestro dispositivo lo podemos poner fuera por ejemplo, para recoger datos durante una noche:
Al llegar la mañana tendremos miles de registros (en este caso más de 36.000), que podemos visualizar con las herramientas de Business Analytics utilizando por ejemplo herramientas disponibles en Open Exchange como el API REST de servidor MDX2JSON y el generador de cuadros de mando DeepSeeWeb , y aquí tenéis una muestra de los resultados:
Niveles de Luminosidad. En esta serie de datos la salida del Sol es claramente visible alrededor de las 5:50:
Gráficos de temperatura y humedad:La correlación negativa entre la humedad y la temperatura es claramente visible.
Conclusión
Con InterSystems IRIS puedes comunicar directamente con una gran cantidad de dispositivos diferentes. Puedes desarrollar muy rápidamente tanto tus soluciones para procesamiento de datos como de visualización - a nuestro equipo le llevó sobre 4 horas construir nuestra propia estación meteorológica, conectarla a IRIS y visualizar los resultados y la mayor parte del tiempo se empleó en el diseño del circuito y en escribir y ajustar el código C.
Links
» Documentation» GitHub - Repositorio del proyecto Original de Eduard Lebedyuk
Pregunta
Yone Moreno · 10 mar, 2022
Hola ¿cómo están?
Estamos indagando cómo recuperar datos mediante una Operación: EnsLib.DICOM.Operation.TCP
Hemos configurado en: Ensemble > Configuración de DICOM > Configuración de DICOM
Las configuraciones de contexto como:
ESBPRE > VNAPRE
VNAPRE > ESBPRE
Siendo para ambas los Contextos de Presentación, los por defecto:
Lo cual hemos generado mediante el código encontrado en el ejemplo del "Namespace: ENSDEMO", el cual hemos incluido en el OnStart() de la Producción:
/// Override this in your Production class to do setup before the Production starts
ClassMethod OnStart(pTimeStarted As %String) As %Status
{
#; Make sure that the associations exist
If '##class(EnsLib.DICOM.Util.AssociationContext).AETExists("ESBPRE","VNAPRE")
{
Do ##class(EnsLib.DICOM.Util.AssociationContext).CreateAssociation("ESBPRE","VNAPRE",$ListBuild($$$IMPLICITVRLETRANSFERSYNTAX))
}
If '##class(EnsLib.DICOM.Util.AssociationContext).AETExists("VNAPRE","ESBPRE")
{
Do ##class(EnsLib.DICOM.Util.AssociationContext).CreateAssociation("VNAPRE","ESBPRE",$ListBuild($$$IMPLICITVRLETRANSFERSYNTAX))
}
If '##class(EnsLib.DICOM.Util.AssociationContext).AETExists("JD-SCU","ENS-SCP")
{
Do ##class(EnsLib.DICOM.Util.AssociationContext).CreateAssociation("JD-SCU","ENS-SCP",$ListBuild($$$IMPLICITVRLETRANSFERSYNTAX))
}
If '##class(EnsLib.DICOM.Util.AssociationContext).AETExists("ENS-SCU","JD-SCP")
{
Do ##class(EnsLib.DICOM.Util.AssociationContext).CreateAssociation("ENS-SCU","JD-SCP",$ListBuild($$$IMPLICITVRLETRANSFERSYNTAX))
}
Quit $$$OK
}
El reto, desafío al cual necesitamos acudir a ustedes para que nos apoyen, guíen, orienten, indiquen, informen, aconsejen, de cómo proceder es el siguiente:
Probamos la Operación de forma directa desde la Producción Web > Acciones > Prueba > ( Rellenamos los datos )
Al acceder a la traza nos encontramos el siguiente hándicap, reto, desafío, al cual necesitamos su auxilio, apoyo, indicaciones para depurarlo, solventarlo y corregirlo:
ERROR <EnsDICOM>NoActiveAssociation: No hay asociación activa para Calling-AET 'ESBPRE y Called-AET 'VNAPRE'
Siendo la visual:
¿Cómo podríamos reparar🔧, depurar 🐞⌨️, entender y solventar este desafío o reto?
Gracias por su lectura y respuestas
🔎 Hemos leido:
https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EDICOM_intro#EDICOM_intro_samples
https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EDICOM_storage_production
https://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EDICOM_associations#EDICOM_associations_import
https://github.com/intersystems-ib/iris-dicom-sample
https://github.com/dcm4che/dcm4che
Cualquier enlace a la documentación 📄, explicación detallada, paso a paso, o instrucciones para juntos indagar, investigar, atender este misterio, son bienvenidos 🙏.
Necesitamos su apoyo, aporte, axilio y respuestas, puesto que es algo bastante distinto a lo habitual y necesitamos mucha orientación, apoyo, y guía 🧭 con esta construcción. 🏗
Gracias 🙇♂️💭
Hola Yone,
Me parece que estás intentado hacer una prueba de envío DICOM por TCP desde Producción > Acciones > Prueba.
Ese tipo de pruebas pueden servirte para casos más sencillos pero no para enviar un mensaje DICOM, que es un poco más complejo.
Si tienes el namespace ENSDEMO, encontrarás ejemplos de producciones que usan ficheros DICOM. Te pueden servir de punto de partida.
Si estás interesado en envío DICOM a través de TCP, necesitarás contar con un simulador. Te paso un ejemplo que utiliza interoperabilidad de IRIS y un simulador (dcm4che). Puedes seguirlo paso a paso: https://github.com/intersystems-ib/iris-dicom-sample
Échale un vistazo, si no consigues avanzar o tienes dudas podemos buscar un hueco la próxima semana y lo comentamos.
Hola Alberto,
Gracias por responder y explicar
Una duda:
¿el uso de las herramientas que comentas es posible para la version HS2017?
¿cual es la versión mínima IRIS para ello?
Lo preguntamos por dos motivos:
Primero: estamos desarollando en:
"" Cache for UNIX (Red Hat Enterprise Linux for x86-64) 2017.2.1 (Build 801_3_18358U) Tue Jul 24 2018 16:36:10 EDT""
Segundo: se presenta el reto o desafío de emplear el simulador para probar DICOM dcm4che
Gracias por responder Hola Yone,
Sí, puedes utilizar HS2017 para implementar integraciones con DICOM.
El ejemplo que te pasé está implementado en IRIS, pero puedes hacer lo mismo en HS2017.
En cuanto al simulador, puedes utilizar el que quieres. Yo he utilizado dcm4che en el ejemplo porque puedes utilizarlo desde línea de comandos en Linux. En el propio ejemplo está incluido cómo hacer algunas llamadas simples para enviar mensajes a través de DICOM TCP. Hola Alberto,
gracias por responder, porque es un apoyo, alivio, auxilio y aporte tus indicaciones, instrucciones y ejemplos
Siguiendo tus indicaciones ubicadas en el ejemplo: https://github.com/intersystems-ib/iris-dicom-sampleHemos realizado 2 pruebas:
Primera prueba: tratamos de guardar DICOM
Siguiendo el ejemplo 1: https://github.com/intersystems-ib/iris-dicom-sample#receiving-dicom-with-embedded-pdf
Circuito:
Siendo la respuesta del sistema destino:
ERROR <EnsDICOM>PeerRejectedAssociation: La contraparte ha rechazado la asociación. Fuente: '' Motivo: ''
Además, realizamos una segunda prueba
Segunda prueba: Consultar y Recuperar, Query / Retrieve: https://github.com/intersystems-ib/iris-dicom-sample#query--retrieve-scenario
Siendo la respuesta por parte del sistema destino:
ERROR <Ens>ErrBPTerminated: Finalizando BP DICOM Query Process # debido a un error: ERROR <EnsDICOM>PeerRejectedAssociation: La contraparte ha rechazado la asociación. Fuente: '%1' Motivo: '%2'> ERROR <EnsDICOM>PeerRejectedAssociation: La contraparte ha rechazado la asociación. Fuente: '%1' Motivo: '%2'
¿ de qué manera, Alberto, nos recomiendan ustedes depurar, buscar, investigar, indagar el porqué de estas 2 excepciones ?
¿ mediante qué mecanismo, o cuál sería tu proceso mental y toma de acciones para organizar, ordenar, entender y sobre todo seguir y dar con la causa de estas excepciones ?
¿ cuál sería la vía correcta para entender, atender, depurar, corregir, y comprender mejor este tipo de integraciones, Alberto ?
Muchas gracias por leer y responder, porque es un gran espaldarazo, auxilio y aporte el hecho de que nos hagas seguimiento y nos vayas indicando, ordenando, explicando, cómo continuar, o en qué ejemplos basarnos
Un saludo
Hola Yone,
En tu caso, parece que el host al que intentas conectar (supongo que es un simulador), está rechazando la conexión.
Quizá porque el documento DICOM que intentas enviar tiene un TransferSyntax que no está configurado. Lo mejor sería que intentaras obtener información / logs en el host que lo está rechazando. Por ejemplo si usas el simulador dcm4che te mostrará información que te puede ayudar a investigar qué ha sucedido.
Yo te recomendaría:
1-Intenta ejecutar el ejemplo que te pasé, utilizando contenedores, y comprueba que todo te funciona bien y comprendes cómo funciona la integración con DICOM.
2-Intenta replicar el comportamiento que te interese en tu propia producción con tu propio simulador. Ten presente la información que te devuelva el simulador. Te ayudará a comprender el proceso de negociación de la conexión y la transferencia.
Pregunta
Javier Sanchis · 13 feb, 2020
Hola a todos,
He estado leyendo algún post en la comunidad pero no he conseguido llegar a una conclusión. Os expongo mi cuestión.
Tengo un código caché, y siguiendo esta guía https://cedocs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=TUNT pero no llego a entender como poder ejecutar esto desde jenkins por ejemplo, sin tener que utilizar la consola, y con ello automatizar el proceso. Es decir, si fuera posible hacerlo, que pasos debería seguir.
muchas gracias Hola Javier! Ya he visto que te han contestado en el developer community
Por lo que preguntas parece que lo que necesitas es ejecutar los tests automáticos, convertir el resultado a JUnit e interpretarlo en Jenkins.
Como te ha dicho Timothy, échale un ojo a JUnitOutput. Te servirá para exportar los resultados de un %UnitTest a formato JUnit.
https://github.com/intersystems-community/zpm/blob/master/src/cls/_ZPM/PackageManager/Developer/UnitTest/JUnitOutput.cls
Por si te sirve de "inspiración", te paso un ejemplo (anticuado - habría que adaptarlo), pero que en esencia al final hacía algo parecido a lo que buscas:
https://github.com/albertoft/widgets-direct/blob/master/WidgetsDirect/Jenkinsfile ¡Qué bien, muy bien! A mí también me ayudó. Hola Alberto!
Muchas gracias por tu respuesta, le echo un ojo ahora mismo.
Anuncio
Esther Sanchez · 4 feb, 2021
¡Hola desarrolladores!
Os queríamos dar las gracias por formar parte de la Comunidad de InterSystems en español. ¡Ya hay más de 300 usuarios registrados en ella!
Día a día, trabajamos para hacerla aún mejor y más útil para todos. Pero nos gustaría saber cómo lo estamos haciendo, y para eso necesitamos conocer vuestra opinión.
Por ello, hemos preparado una breve encuesta para saber qué pensáis de la Comunidad en español, si os resulta útil y qué podríamos mejorar.
👉🏼 Encuesta sobre la Comunidad de Desarrolladores en español 👈🏼
Nota: Os llevará menos de 5 minutos responderla.
También podéis dejar vuestra opinión en los comentarios de esta publicación.
¡Muchas gracias a todos! ¡Hola a todos!
¿Ya habéis respondido a la encuesta sobre la Comunidad de Desarrolladores en español?
Si es así, ¡muchas gracias!
Si no, ¡aún estáis a tiempo de ayudarnos a hacerla aún mejor!! Os llevará menos de 5 minutos...
➡️ Encuesta sobre la Comunidad de Desarrolladores en español Este jueves 4 termina el plazo para recibir vuestras respuestas a la Encuesta sobre la Comunidad!
Si aún no habéis respondido, aquí tenéis el enlace, os llevará menos de 5 minutos completarla:
➡️ Encuesta sobre la Comunidad de Desarrolladores en español
¡Os leemos a todos y nos encanta saber vuestra opinión! ¡Muchas gracias!