Encontrar

記事
· 2025年10月23日 1m read

Reviews on Open Exchange - #57

If one of your packages on OEX receives a review, you get notified by OEX only of YOUR own package.   
The rating reflects the experience of the reviewer with the status found at the time of review.   
It is kind of a snapshot and might have changed meanwhile.   
Reviews by other members of the community are marked by * in the last column.

I also placed a bunch of Pull Requests on GitHub when I found a problem I could fix.    
Some were accepted and merged, and some were just ignored.     
So if you made a major change and expect a changed review, just let me know.

# Package Review Stars IPM Docker *
1 DevHub Big helper for daily work 5.5 y y  
2 GBLSizeMonitor Super Graphics 5.5* 5.5 y y  
3 Erralyzer visualized SMP features 5.0 y y  
4 Free DBsize with Swagger great remote access 5.0 y y *
5 IRISConfigDashboard Easy to navigate 5.0 y y  
6 ObjectScript-Native-API-demo Cross server working without ECP or MIRROR 5.0 y y *
7 Stream-Sample-for-Beginners Not for beginners only 5.0 y y *
8 swaggertools-jsonviewer interesting setup analysis 5.0   y  
9 Interop-LookupTable handy Table maintenance 4.9   y  
10 inquisidor refresh your Spanish 4.5   y  
ディスカッション (0)1
続けるにはログインするか新規登録を行ってください
記事
· 2025年10月23日 9m read

IKO Plus: Operator Works From Home - IrisCluster Provisioning Across Kubernetes Clusters

IKO Helm Status: WFH

Here is an option for your headspace if you are designing an multi-cluster architecture and the Operator is an FTE to the design.  You can run the Operator from a central Kubernetes cluster (A), and point it to another Kubernetes cluster (B), so that when the apply an IrisCluster to B the Operator works remotely on A and plans the cluster accordingly on B.  This design keeps some resource heat off the actual workload cluster, spares us some serviceaccounts/rbac and gives us only one operator deployment to worry about so we can concentrate on the IRIS workloads.

IKO woke up and decided against the commute for work, despite needing to operate a development workload of many IrisClusters at the office that day.  Using the saved windshield time, IKO upgraded its helm values on a Kubernetes cluster at home, bounced itself, and went for a run.  Once settled back in, inspecting its logs, it could see it had planned many IrisClusters on the Office Kubernetes cluster, all at the cost of its own internet and power.

Here is how IKO managed this...

Clusters

Lets provision two Kind clusters, ikohome and ikowork.

 
ikokind.sh

After running the above, you should have two clusters running, loaded with the Cilium CNI and ready for business.

Install IKO at HOME 🏠

First we need to make the home cluster aware of the work cluster and load up its kubeconfig as a secret, you can get this done with the following.

kubectl create secret generic work-kubeconfig --from-file=config=ikowork.kubeconfig --kubeconfig ikohome.kubeconfig

Now, we need to make some changes to the IKO chart to WFH.

  • Mount the kubeconfig Secret as a Volume in the Operator
  • point to the kubeconfig in the operator arguments ( --kubeconfig )

The deployment.yaml in its entirety is below, edited right out of the factory, but here are the important points called out in the yaml

Mount

        volumeMounts:
...
        - mountPath: /airgap/.kube
          name: kubeconfig
          readOnly: true
      volumes:
...
      - name: kubeconfig
        secret:
          secretName: work-kubeconfig
          items:
          - key: config
            path: config

Args

The args to the container too... I tried this with the env "KUBECONFIG" but after taking a look at the controller code, found out there was a precedence to such things.

      containers:
      - name: operator
        image: {{ .Values.operator.registry }}/{{ .Values.operator.repository }}:{{ .Values.operator.tag }}
        imagePullPolicy: {{ .Values.imagePullPolicy  }}
        args:
        - run
...
        - --kubeconfig=/airgap/.kube/config
...

 

 
deployment.yaml

Chart

Same with the values.yaml, here I disabled the mutating and validating webhooks.

 
values.yaml

Deploy the chart @ home and make sure its running.

 

Install CRDS (only) at WORK 🏢

This may be news to you, it may not, but understand that the operator actually installs the CRDS in the cluster, so in order to work from home, the CRDS need to exist in the work cluster (but without the actual operator). 

For this we can pull this maneuver:

kubectl get crd irisclusters.intersystems.com --kubeconfig ikohome.kubeconfig -o yaml > ikocrds.yaml
kubectl create -f ikocrds.yaml --kubeconfig ikowork.kubeconfig

IKO WFH

Now, lets level set the state of things:

  • IKO is running at home, not at work
  • CRDS are loaded at work, only

When we apply IrisClusters at work, the operator at home will plan and schedule them from home.

Luckily, the whole burn all .gifs things in the 90's  got worked out for the demo.

 

Operator


IrisCluster




💥

1件の新着コメント
ディスカッション (1)2
続けるにはログインするか新規登録を行ってください
記事
· 2025年10月23日 1m read

[Dica Rápida] - Como usar URL em serviços REST API sem distinção entre maiúsculas e minúsculas

Olá a todos,

Esta é uma dica rápida sobre como usar URLs em serviços REST API sem distinção entre maiúsculas e minúsculas.

Se você tem uma classe que estende de %CSP.REST e Ens.BusinessService para criar um serviço REST API, e você definiu seu WebApplication em minúsculas:

XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
    <Route Url="/user" Method="POST" Call="User"/>
    <Route Url="/login" Method="POST" Call="Login"/>
</Routes>
}

Ele só aceitará URLs em minúsculas, por exemplo: http://myserver/myproduction/user

Se houver qualquer caractere em maiúscula, a URL não funcionará: http://MyServer/MyProduction/user

É fácil de corrigir, basta adicionar a expressão regular (?i) para permitir qualquer rota sem distinção entre maiúsculas e minúsculas.

XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
    <Route Url="(?i)/user" Method="POST" Call="User"/>
    <Route Url="(?i)/login" Method="POST" Call="Login"/>
</Routes>
}

Agora, ele aceita ambas as URLs:

http://myserver/myproduction/user

http://MyServer/MyProduction/user

Boa codificação!

ディスカッション (0)1
続けるにはログインするか新規登録を行ってください
記事
· 2025年10月23日 10m read

La nueva validación basada en perfiles de servidor FHIR

Una novedad que apareció en la versión 2024.1 de InterSystems IRIS for Health y que quizá te pasó desapercibida. Se trata de la capacidad de realizar una validación basada en perfiles FHIR.

 

En este artículo os ofreceré una visión general básica de esta funcionalidad.

Si FHIR es importante para vosotros, deberíais probar sin duda esta nueva característica, así que seguid leyendo.

 

Contexto

El estándar FHIR define una operación llamada $validate. Esta operación está pensada para ofrecer una API que permita validar recursos.

Para entender mejor la validación FHIR en general, podéis consultar esta documentación de FHIR.

También podéis ver la sesión del Global Summit 2023, “Realización de validaciones FHIR avanzadas”, en la que en la primera parte se explican los distintos tipos de validaciones.

Parte de esta validación consiste en comprobar los recursos frente a perfiles específicos. Podéis ver más sobre esto en el apartado de Profiling.

Para ilustrarlo con un ejemplo sencillo, la definición base de FHIR para el recurso Patient establece que la cardinalidad del campo identifier es “0..”, lo que significa que un paciente podría no tener ningún identificador (cero) y seguir siendo válido. Sin embargo, el perfil US Core Patient define una cardinalidad de “1..”, lo que implica que un paciente sin identificador no sería válido.

Otros ejemplos, siguiendo el modelo del US Core Patient anterior, serían el uso de extensiones como race o birthsex.

Si queréis aprender más sobre el FHIR Profiling, podéis echar un vistazo a una sesión del Global Summit 2022 presentada por @Patrick Jamieson, “Using FHIR Shorthand”, en la que Pat explica el uso de FSH (FHIR Shorthand), pero comienza abordando el tema general del Profiling.

En versiones anteriores, nuestro servidor FHIR no admitía este tipo de validación —la validación basada en perfiles—, pero desde la versión 2023.3 ya está disponible.

Uso

Nuestra documentación incluye una sección sobre cómo llamar a $validate para realizar una validación basada en perfiles.

Hay dos formas básicas de llamar a la operación $validate.

Perfil en la URL de la consulta
Una de ellas consiste en enviar una petición POST con el recurso en el cuerpo de la solicitud y el perfil como un parámetro en la URL.

Por ejemplo, en Postman:

O usando curl (tened en cuenta la codificación de las barras en el valor del parámetro de la URL del perfil; Postman se encarga de eso por vosotros):

 curl --location 'http://fhirserver/endpoint/Patient/$validate?profile=http%3A%2F%2Fhl7.org%2Ffhir%2Fus%2Fcore%2FStructureDefinition%2Fus-core-patient%7C3.1.0' --header 'Content-Type: application/fhir+json' --header 'Accept: application/fhir+json' --header 'Authorization: Basic U3VwZXJVc2VyOnN5cw==' --data "@data.json"

Mientras que el archivo data.json mencionado arriba incluye, por ejemplo, este paciente válido del US Core:

 
Recurso de paciente en JSON

La respuesta de esta operación es un recurso OperationOutcome.

Si el recurso es válido (como se indicó anteriormente), deberíais esperar obtener este tipo de respuesta:

{
    "resourceType": "OperationOutcome",
    "issue": [
        {
            "severity": "information",
            "code": "informational",
            "details": {
                "text": "All OK"
            }
        }
    ]
}

Pero si, por ejemplo, omito los identificadores del recurso anterior, obtendré este OperationOutcome:

{
    "resourceType": "OperationOutcome",
    "issue": [
        {
            "severity": "error",
            "code": "invariant",
            "details": {
                "text": "generated-us-core-patient-1: Constraint violation: identifier.count() >= 1 and identifier.all(system.exists() and value.exists())"
            },
            "diagnostics": "Caused by: [[expression: identifier.count() >= 1, result: false, location: Patient]]",
            "expression": [
                "Patient"
            ]
        }
    ]
}

 

Perfil en el cuerpo de la consulta
La otra forma de enviar los datos a $validate es mediante un POST con el recurso dentro de un array de parámetros, junto con el perfil y otras opciones.

En Postman esto se verá así:

Con curl:

curl --location 'http://fhirserver/endpoint/Patient/$validate' --header 'Content-Type: application/fhir+json' --header 'Accept: application/fhir+json' --header 'Authorization: Basic U3VwZXJVc2VyOnN5cw==' --data "@data.json"

Tened en cuenta que la URL no incluye un perfil, pero ahora el contenido del cuerpo (o data.json en el ejemplo anterior) tiene este aspecto:

{
    "resourceType": "Parameters",
    "parameter": [
        {
            "name": "mode",
            "valueString": "profile"
        },
        {
            "name": "profile",
            "valueUri": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient|3.1.0"
        },
        {
            "name": "resource",
            "resource": {
                "resourceType": "Patient"
            }
        }
    ]
}

He excluido el recurso de paciente real, ya que es el mismo que en los ejemplos anteriores.

Pero lo que es diferente aquí es el elemento del parámetro mode, el del perfil, y que el recurso viene dentro de su propio elemento de parámetro, simplemente llamado “resource”.

Consultad la documentación mencionada anteriormente para ver más opciones de mode, incluyendo los casos en los que se puede incluir un ID en la URL (para validar, por ejemplo, una actualización o eliminación).

Para vuestra comodidad, he creado un paquete simple de Open Exchange que incluye una colección de Postman con solicitudes de ejemplo como las anteriores.

Posibles errores

Si omitís una versión para el perfil en el formato<profile URI>|<version number>, obtendréis un error <HSFHIRErr>ProfileVersionRequired  

Recibiríais un código de estado 400 y este tipo de OperationOutcome:

{
    "resourceType": "OperationOutcome",
    "issue": [
        {
            "severity": "error",
            "code": "invalid",
            "diagnostics": "<HSFHIRErr>ProfileVersionRequired",
            "details": {
                "text": "Profile URI 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient' does not include a version number.  Version number is required for profile validation."
            }
        }
    ]
}

Si proporcionáis un número de versión que no existe en el endpoint FHIR, obtendréis un error de tipo not-supported (esta vez el estado HTTP será 200).

Vuestro OperationOutcome tendrá, por ejemplo, este aspecto:

{
    "resourceType": "OperationOutcome",
    "issue": [
        {
            "severity": "error",
            "code": "not-supported",
            "details": {
                "text": "Profile 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient|15' is not supported"
            },
            "expression": [
                "Patient"
            ]
        }
    ]
}

Via Código

Tened en cuenta que, como alternativa a llamar a la operación $validate mediante la API REST estándar, internamente, si el caso de uso lo permite, también podéis llamar a un método de clase.

De forma similar al método que ya existía HS.FHIRServer.Util.ResourceValidator:ValidateResource() (mencionado también en la documentación), ahora existe un nuevo método llamado ValidateAgainstProfile() que podéis utilizar.

Alcance

Es importante tener en cuenta que actualmente (versión 2024.1) este tipo de validación (basada en perfiles) solo se realiza como parte de la operación $validate, pero no cuando se crean o actualizan recursos. En esos casos se realiza una validación más “básica”. Por tanto, si lo deseáis, podéis ejecutar vuestros recursos a través de la validación más “avanzada” basada en perfiles antes de hacer un POST o PUT.

Otras opciones podrían estar disponibles en versiones futuras.

 

Notas de configuración

En general, la buena noticia es que el servidor FHIR se encargará de la mayor parte de la configuración del validador de perfiles por vosotros.

Lo que sí debéis aseguraros es de tener un JDK de Java 11 compatible (actualmente el de Oracle o el de OpenJDK).

Podéis encontrar más detalles en la documentación de configuración del servidor de validación de perfiles.

Básicamente, lo que ocurre en segundo plano es que nos aseguramos de que haya un servidor de lenguaje externo (Java) en ejecución, para poder ejecutar el archivo JAR del validador (ubicado en la carpeta de instalación, bajo dev/fhir/java). Por cierto, si echáis un vistazo a la carpeta de registros y veis algunas advertencias, como:

CodeSystem-account-status.json : Expected: JsonArray but found: OBJECT for element: identifier

no os preocupéis, es normal. El validador carga muchos perfiles por defecto y algunos de ellos tienen pequeños errores de formato).

Así que, si revisáis vuestra lista de servidores de lenguaje externo, deberíais ver algo como esto:

Tened en cuenta que, cuando el validador necesita validar por primera vez contra un perfil, debe cargarlos, por lo que para mejorar el rendimiento podéis llamar al método HS.FHIRServer.Installer:InitalizeProfileValidator():

set status = ##class(HS.FHIRServer.Installer).InitializeProfileValidator(.error)

Esto también se menciona en la documentación antes citada sobre la configuración del validador.

De hecho, podríais incluir esta llamada en la rutina de inicio %ZSTART de vuestra instancia.

Y esto también se menciona en la referencia de clases relacionada:

Se recomienda llamar a este método después de reiniciar la instancia o el servidor de lenguaje externo, para evitar la pérdida de rendimiento que supondría cargar los perfiles durante la operación de validación.

 

Próximamente...

En las próximas versiones planeamos ofrecer más funcionalidades dentro y alrededor del validador.

Pero, por ejemplo, incluso hoy, si queréis realizar una validación basada en un servidor de terminología externo (como para los códigos LOINC), podéis usar un enfoque diferente, uno explicado y demostrado en la sesión del Global Summit mencionada anteriormente, basado en el ejemplo de mi compañero @Dmitry Zasypkin (disponible en Open Exchange).

 

Agradecimientos especiales

Gracias a @Kimberly Dunn, quien fue una fuente inestimable de información durante el análisis de esta nueva función y la preparación de este artículo.

(*) Gracias a Microsoft Bing y su Image Creator impulsado por DALL-E 3, que creó la imagen de arriba para mí.

ディスカッション (0)1
続けるにはログインするか新規登録を行ってください
質問
· 2025年10月23日

Why Dubai Homeowners Are Switching to Tankless Water Heaters

Picture this — it’s a busy Dubai morning, your family is getting ready, and suddenly… the hot water runs out halfway through your shower. Frustrating, right? That’s exactly the moment many homeowners decide they’ve had enough of old-fashioned water heaters. Across the city, more and more people are turning to tankless water heaters — and for good reason. They’re sleek, energy-efficient, and deliver hot water the moment you need it, no waiting, no stress.

Let’s dive into why this modern upgrade is becoming a must-have in Dubai homes and how a trusted plumber Dubai can make the switch effortless for you.

1.​‍​‌‍​‍‌​‍​‌‍​‍‌ Say Goodbye to Running Out of Hot Water

In a typical water heater, hot water is kept in a limited tank. First, the stored hot water is utilized, and then you are required to wait for the water in the tank to be heated again. This waiting period is very inconvenient, especially when you are in a hurry. Water heaters without tanks actually heat water immediately as the water is being delivered, making it impossible for the water to run out of hot water. In fact, you can perform multiple activities, such as taking a shower, washing dishes, and doing laundry, simultaneously without the common problem of the water turning cold.

It is very common for families in Dubai to be satisfied with the conveniences that these heaters provide. When questioned about the tankless water heater, a Downtown Dubai resident answered, “Before the heater malfunctioned, we would schedule our showers according to the heater usage. With our tankless system, we don’t have to give it a single thought anymore.”

First of all, these water heating gadgets are not only comfortable for use — they are also friendlier to the environment because they consume less power. They also cut down on power costs since the water can only be heated when it is required. Regarding the regular increment in utility fees, the homeowners perceive it as a wise investment in the long run. However, do not forget to get an expert plumber in Dubai to diagnose and install a suitable tank for your family's water consumption.

2. Sleek Design, More Space, and Less Hassle

The Homes in Dubai are characterized by a mix of style and utility, and therefore, the extravagant water tank does not fit this picture. Tankless heaters are small, simple, and camouflaging, which is another reason why people are leaving the traditional water heaters for tankless ones. Having one on a wall, hiding it in a cabinet, or installing it outside are among the ways you can place the heater.

If you are remodeling or building a new house, it can totally change the look of your bathroom or laundry. You will not see ugly, rusting water heaters, but rather clean lines and modern efficiency.

A Professional plumber in Dubai who is equipped with the knowledge of Plumbing systems can assist you in determining the best point for functional as well as aesthetic installation of the device.

3. Fewer Repairs, Longer Life, and Cleaner Water

Time to tell the truth — conventional heaters are a pain in the neck. They face a variety of issues, including rust, sediment, and leaks; therefore, they often need frequent repairs. Unlike traditional water heaters, tankless ones are dependable and durable. If the owner treats it properly, it can easily last for 15-20 years. That is almost two times the lifespan of a tank model.

Moreover, since there is no water storage, the problems associated with the growth of bacteria and bad smell are eliminated. However, in case you live in an area where the water is hard, you may have to call a plumber from time to time for descaling so that everything goes smoothly.

This is just another advantage of the device — there will no longer be surprise water spillage from a broken tank. Less trouble, less maintenance, and more peace of mind. Combine that with efficient Drain Cleaning Services in Dubai, and you can be sure that your home's entire plumbing system will remain in good shape for a long time to ​‍​‌‍​‍‌​‍​‌‍​‍‌come.

FAQs About Tankless Water Heaters

Q1: Do tankless heaters work for large families?

Absolutely. Your plumber in Dubai can recommend the right size to meet your household’s hot water needs, even if multiple people are using water at once.

Q2: Are they expensive to install?

While the upfront cost is higher, the long-term savings on electricity and repairs make it worth every dirham.

Q3: How often do they need servicing?

Once a year is usually enough. A quick maintenance check keeps performance top-notch and prevents buildup.

Q4: Can they help with water conservation?

Yes — since they heat water instantly, you waste less while waiting for it to warm up.

In a Nutshell

Switching to a tankless water heater isn’t just about convenience — it’s about upgrading your home’s comfort and efficiency. Imagine never running out of hot water again, freeing up space, and cutting down on energy costs.

Dubai homeowners are becoming aware that contemporary living requires contemporary solutions. Therefore, if you are willing to implement the change, contact a trustworthy plumber in Dubai who is Plumbing Dubai system. Besides, it is a good idea to have regular Drain Cleaning Services in Dubai appointments for efficient water drainage.

In the end, it’s not just about hot water — it’s about living smarter, cleaner, and more comfortably. Tankless water heaters deliver exactly that, one perfectly warm shower at a time.

ディスカッション (0)1
続けるにはログインするか新規登録を行ってください