Limpiar filtro
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!
Pregunta
Evgeny Shvarov · 15 abr, 2021
¡Hola amigos!
A menudo, durante la depuración, quieres conocer los valores de todos los parámetros.
Utilizar VSCode Debugger no es una opción.
¿Qué se podría usar para saber qué parámetros vinieron al método?
¿Existe una macro "mágica" que almacene todas las variables con sus nombres en un global?
¿Alguna idea? ¡Gracias!
@Julius.Kavay ha dado una muy buena alternativa.
En lugar de insertar debug_macros, prueba la utilidad TRACE de Intersystems.
write $$DIR^TRACE("c:\Temp\") ; to set an output directory
write $$ON^TRACE(jobnr) ; the pid of the process you want to trace
; zn "appNamespace"
; do ^yourProgram
; zn "%SYS"
write $$OFF^TRACE(jobnr) ; to stopp the trace
do ^TRACE ; to display the trace result
TRACE muestras las llamadas a métodos/funciones con argumentos.
Para hacer uso de ella, debéis de estar en el namespace %SYS... o podéis mapearla al namespace %ALL y así la podréis utilizar desde cualquier sitio. No aparece actualmente en la documentación oficial, pero podéis encontrar información de uso ejecutando do ^TRACE y en la propia rutina ^TRACE.int (podéis ver el código fuente completo desde el portal, el Studio, VS Code,...)
Anuncio
Esther Sanchez · 12 mayo, 2021
¡Hola desarrolladores!
Os invitamos a un nuevo webinar en español: "Aprende ObjectScript desde cero", el martes 25 de mayo, a las 4:00 PM (CEST).
Para todos aquellos que no tienen ni idea de ObjectScript y quieren empezar a utilizarlo, o para aquellos que llevan tiempo desarrollando con el lenguaje de programación de InterSystems sin saber cómo lo hacen, vamos a explicar los conceptos básicos de ObjectScript, descubrir algunas trampas y mostrar algunos trucos muy útiles.
Además, haremos una ginkana en directo para demostrar lo aprendido. Los tres primeros clasificados ganarán un polo de la Comunidad de Desarrolladores... ¡y algunas cosas más!¡Os esperamos!
➡️ David Reche, el ponente del webinar, os invita personalmente a asistir! >>➡️ Podéis registraros aquí >>
El próximo martes es el webinar de ObjectScript.
Además de aprender, pasaremos un rato muy divertido jugando a un juego de preguntas y respuestas online sobre lo explicado en el webinar. Competiremos unos contra otros y el podio final mostrará a los ganadores!
¡Apúntate antes de que se te olvide! :D Empieza la cuenta atrás... ¡mañana ya es el webinar!
Durante 30 minutos, explicaremos los conceptos básicos de ObjectScript, descubriremos algunas trampas y mostraremos algunos trucos muy útiles.
Y, al terminar el webinar, haremos una ginkana en directo para que demostréis lo aprendido! 😃
¡Os esperamos!
Artículo
Muhammad Waseem · 29 sep, 2021
https://www.appeon.com/products/powerbuilder
Appeon PowerBuilder es una herramienta de desarrollo empresarial que permite crear componentes y aplicaciones empresariales basadas en datos.Es un producto de una suite de Appeon que ofrece las herramientas para desarrollar aplicaciones cliente/servidor, web, móviles y distribuidas.
En este artículo, mostraré los pasos para conectarse a Caché con Appeon PowerBuilder usando ODBC.
Paso 1 : Asegúrate de que la opción "ODBC Driver" está seleccionada al instalar IRIS:
Paso 2: Configura la fuente de datos ODBC IRIS mediante el Administrador de fuentes de datos ODBC:
Paso 3: Configura la fuente de datos ODBC de InterSystems:
Paso 4: Prueba la conexión (asegúrate de que la instancia de IRIS se está ejecutando):
Paso 5: Desde PowerBuilder, abre "Database profiles", seleccione "ODB ODBC" de la lista y haz clic en el botón "New...":
Paso 6: Selecciona la fuente de datos "IRISHealth User" que creamos usando el administrador de ODBC:
Paso 7: Prueba la conexión en la pestaña "Preview" haciendo clic en el botón "Test connection":
¡Enhorabuena! ¡Nos hemos conectado con Caché!Ahora podemos ver Tablas y Datos utilizando el pintor de bases de datos de PowerBuilder.
¡Espero que os resulte útil!
¡Gracias!
Anuncio
Esther Sanchez · 3 mar, 2022
¡Hola desarrolladores!
Muchísimas gracias a todos los que habéis participado, de una forma u otra, en el 1er concurso de artículos técnicos en español! Hemos recibido
🌟 8 ARTÍCULOS INCREÍBLES 🌟
Y... ¡llegó el momento de anunciar los mejores!
Estos son los ganadores y sus artículos:
⭐️ Premios de los expertos – los ganadores han sido elegidos por expertos de InterSystems:
🥇 Primer puesto: Enviando mensajes a Kafka, escrito por @Daniel.Aguilar
🥈 Segundo puesto: Cómo convertirse en un señor del tiempo - El Nacimiento, escrito por @Francisco.Lopez1549
🥉 Tercer puesto: Implementación de patrones de proyecto utilizando el lenguaje Caché ObjectScript, escrito por @Marcio.Pereira
⭐️ Premio de la Comunidad – el ganador es elegido por los miembros de la Comunidad y es el artículo con mayor número de "likes":
🏆 Cómo convertirse en un señor del tiempo - El Nacimiento, escrito por @Francisco.Lopez1549
¡Enhorabuena a todos los ganadores!
¡Y un fuerte aplauso al resto de participantes!
@Robert.Cemper1003
@Laura.BlázquezGarcía
@Nancy.Martinez
@Yone.Moreno
¡GRACIAS por vuestro esfuerzo y por contribuir en la Comunidad!!!
Los premios están en producción. Contactaremos con los ganadores para enviárselos lo antes posible. Enhorabuena a los premiados. Muy buenos artículos han salido. Hay que repetirlo porque hay mucha calidad en la comunidad ¡Enhorabuena por tus dos premios!! 🎊🎊 ¡Felicitaciones a todos! ¡Gracias por tu contribución! Muchas felicidades a los ganadores y a todos los participantes
Anuncio
Esther Sanchez · 26 abr, 2022
¡Hola desarrolladores!
El Primer Concurso de Artículos Técnicos en Portugués ha terminado.
Hemos recibido: 🔥6 artículos increíbles 🔥
¡Muchísimas gracias a todos los que habéis participado!
Y llegó el momento de anunciar los mejores...
Estos son los ganadores y sus artículos:
⭐️ Premios de los expertos – los ganadores han sido elegidos por expertos de InterSystems:
🥇 Primer puesto: Utilizando HealthShare para normalização de resultados de SARS-CoV-2/COVID-19 escrito por @Renan.Santos
🥈 Segundo puesto: Introdução à análise de dados com IRIS e Pandas escrito por @Henry.HamonPereira
🥉 Tercer puesto: HealthShare: criando o ecossistema de atendimento orientado a dados escrito por @Yuri Marx
⭐️ Premio de la Comunidad – el ganador es elegido por los miembros de la Comunidad y es el artículo con mayor número de "likes":
🎉 Utilizando HealthShare para normalização de resultados de SARS-CoV-2/COVID-19 escrito por @Renan.Santos
¡Enhorabuena a todos los ganadores!
Y un fuerte aplauso al otro participante:
@Julio.Esquerdo
¡GRACIAS por vuestro esfuerzo y por contribuir en la Comunidad!!!
Los premios están en producción. Contactaremos con los ganadores para enviárselos lo antes posible. ¡Felicitaciones a todos los ganadores! Y por los grandes artículos publicados.
¡Estoy disponible para ayudarte siempre que lo necesites! Muito obrigado Renan, pela disposiçao!
Anuncio
Esther Sanchez · 21 mar, 2023
¡Hola Comunidad!Hemos realizado una integración entre Open Exchange y Global Masters. Ahora, cuando hagáis una reseña de una aplicación en Open Exchange, conseguiréis puntos e insignias automáticamente, no tenéis que hacer nada más! Conseguiréis:
💰 200 puntos automáticamente por cada reseña publicada en Open Exchange
🏆 Puntos extra e insignias por número de reseñas:
Insignia "Open Exchange Reviewer"Por la 1ª reseña publicada
200 puntos
Insignia "Advanced Open Exchange Reviewer"Por 5 reseñas publicadas
500 puntos
Insignia "Bronze Open Exchange Reviewer"Por 10 reseñas publicadas
1000 puntos
Insignia "Silver Open Exchange Reviewer"Por 25 reseñas publicadas
2500 puntos
Insignia "Gold Open Exchange Reviewer"Por 50 reseñas publicadas
5000 puntos
Las reseñas ayudan a otros desarrolladores a encontrar más rápido la aplicación adecuada. Y ofrecen información muy útil para todos.¡Nos encantaría ver más reseñas en Open Exchange!¿Cómo hacer una reseña? ¡Es facilísimo! Os lo explicamos en este vídeo:
Psss... Si aún no pertenecéis a Global Masters, la plataforma de gamificación de InterSytems, podéis daros de alta aquí usando vuestras credenciales SSO de InterSystems.
Artículo
Daniel Franco · 19 ago, 2020
Ejecutar modelos predictivos de forma nativa en un "Business Process" ("Proceso Empresarial") de InterSystems IRIS siempre ha sido, por supuesto, el objetivo de nuestro soporte para PMML, pero de alguna forma nunca formó parte del paquete porque había algunas dependencias y elecciones que era necesario analizar y decidir. En cualquier caso, gracias a algunas presiones y al código ofrecido amablemente por @Amir.Samary (¡gracias de nuevo, Amir!), finalmente conseguimos empaquetarlo en un repositorio de GitHub para que lo disfruteis, lo valoreis y hagáis sugerencias.
El repositorio contiene una "Business Process" ("Process Empresarial") genérica, que funciona con cualquier modelo PMML usando una matriz para pasar entradas al modelo, y también contiene una herramienta que generará una BO ("Business Operation" - "Operación Empresarial") para tus clases PMML. La última supone un paso adicional (de una línea) durante la preparación, pero generará objetos dedicados de solicitud y respuesta, lo que será mucho más conveniente al conectar propiedades en el creador de solicitudes cuando se trabaje con modelos complejos.
A continuación del código de la herramienta, también hay una "Producción" de muestra, que aprovecha ambos enfoques.
Déjanos saber tu opinión y en base a los comentarios podremos elegir la mejor forma de incluirlo finalmente en el paquete. Y, por supuesto, siempre nos alegra saber cómo habeis estado usando modelos PMML hasta ahora.
Artículo
Alberto Fuentes · 15 nov, 2022
YASPE es el sucesor de YAPE (Yet Another pButtons Extractor). YASPE ha sido escrito desde cero con muchos cambios internos para facilitar el mantenimiento y añadir mejoras.
Funcionalidades de YASPE:
- Analizar y representar gráficamente los archivos de InterSystems Caché pButtons e InterSystems IRIS SystemPerformance para un rápido análisis de rendimiento de las métricas de IRIS y del Sistema Operativo.
- Facilitar un análisis profundo, creando gráficos tanto *ad-hoc* como combinando métricas de IRIS y del Sistema Operativo con la opción "Pretty Performance".
- La opción "System Overview" te ahorra tener que buscar en los archivos SystemPerformance detalles del sistema u opciones de configuración comunes.
YASPE está escrito en Python y está disponible en GitHub como código fuente o para contenedores Docker en:
> - https://github.com/murrayo/yaspe
---
> YASPE está más centrado en las versiones y Sistema Operativo actuales de IRIS. Si tienes versiones más antiguas y tienes problemas con YASPE, comprueba si puedes ejecutar correctamente tus archivos de rendimiento con YAPE. Si tienes problemas, no dudes en preguntarme a través de GitHub.
---
## Ejemplos
### Archivos de salida
Las opciones incluyen:
- Gráficos en HTML o PNG para todas las columnas en mgstat y vmstat o windows perfmon y salida a carpetas.
- Es opcional crear gráficos para iostat ya que puede llevar mucho tiempo si hay una lista de discos grande.
- Un fichero CSV para posterior procesado manual, por ejemplo, con Excel.

### Pretty Performance
Debajo está el gráfico de ejemplo, Glorefs (mgstat) y Uso Total de CPU (vmstat).
[](https://github.com/murrayo/yaspe/blob/main/images/Glorefs_and_CPU_Utilisation_-_Sample_site_name_Monday_17_Jan_2022.png)
Esta es una de las imágenes predeterminadas, que incluye un zoom para un momento específico (o por defecto de 13:00-14:00).
[](https://github.com/murrayo/yaspe/blob/main/images/CPU_Utilisation_1000_1100.png)
### Descripción del sistema
_yaspe_ incluye una descripción del sistema y una comprobación básica de la configuración (`-s`)
Esta comprobación está diseñada para evitar estar rebuscando en el archivo SystemPerformance para encontrar los detalles del sistema. Este es un ejemplo de`overview.txt`:
```text
System Summary for your site name
Hostname : YOURHOST
Instance : SHADOW
Operating system : Linux
Platform : N/A
CPUs : 24
Processor model : Intel(R) Xeon(R) Gold 6248 CPU @ 2.50GHz
Memory : 126 GB
Shared memory : globals 71680 MB + routines 1023 MB + gmheap 1000 MB = 73,703 MB
Version : Cache for UNIX (Red Hat Enterprise Linux for x86-64) 2018.1.4 (Build 505_1U) Thu May 28 2020 10:11:16 EDT
Date collected : Profile run "24hours" started at 16:15:00 on Nov 22 2021.
Warnings:
- Journal freeze on error is not enabled. If journal IO errors occur database activity that occurs during this period cannot be restored.
- swappiness is 10. For databases 5 is recommended to adjust how aggressive the Linux kernel swaps memory pages to disk.
- Hugepages not set. For performance, memory efficiency and to protect the shared memory from paging out, use huge page memory space. It is not advisable to specify HugePages much higher than the shared memory amount because the unused memory are not be available to other components.
- dirty_background_ratio is 10. InterSystems recommends setting this parameter to 5. This setting is the maximum percentage of active memory that can be filled with dirty pages before pdflush begins to write them.
- dirty_ratio is 30. InterSystems recommends setting this parameter to 10. This setting is the maximum percentage of total memory that can be filled with dirty pages before processes are forced to write dirty buffers themselves during their time slice instead of being allowed to do more writes. These changes force the Linux pdflush daemon to write out dirty pages more often rather than queue large amounts of updates that can potentially flood the storage with a large burst of updates
Recommendations:
- Review and fix warnings above
- Set HugePages, see IRIS documentation: https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=GCI_prepare_install#GCI_memory_big_linux
- Total memory is 128,755 MB, 75% of total memory is 96,566 MB.
- Shared memory (globals+routines+gmheap) is 73,703 MB. (57% of total memory).
- Number of HugePages for 2048 KB page size for (73,703 MB + 5% buffer = 77,388 MB) is 38694
All instances on this host:
- >SHADOW 2018.1.4.505.1.a 56772 /cachesys
```
---