Nueva publicación

Encontrar

Artículo
· 15 hr atrás Lectura de 2 min

Highlights from Two Inspiring Days at France & Benelux READY 2026

France & Benelux READY 2026 has just come to an end, and once again, these two days demonstrated how dynamic, curious, and engaged the Developer Community truly is. Here is a look back in words and images at this great edition.

The event kicked off with welcome remarks from @Adeline Icard and @Geoffroy Vitoux, setting the tone for the days ahead: innovation, sharing, and collaboration.

@Don Woodlock then delivered an inspiring presentation on InterSystems values and culture - a standout moment that strongly resonated with the audience.

The first sessions immediately immersed participants in concrete and inspiring topics, with rich discussions around InterSystems technologies and their real-world use cases.

Throughout READY, we had the pleasure of meeting many participants during the sessions.

The questions, discussions, and experience sharing highlighted a strong interest in practical, hands-on topics, whether from a developer, architect, or manager perspective. I was also lucky to capture a moment with @Adeline Icard, one of the event’s organizers.

The gala dinner provided an opportunity to continue conversations in a more relaxed setting. Michel Amous opened the evening with a wonderful speech.

The setting was simply exceptional: the Les Ombres restaurant by chef Alain Ducasse, offering a spectacular view of the Eiffel Tower.

With @Anastasia Dyubaylo and @Evgeny Shvarov.

Later in the evening, @Adeline Icard introduced soprano Laure Poissonnier, who delighted us with her performance.

As is tradition at these events, we also enjoyed a visit to the permanent collection of the Musée du quai Branly, discovering particularly fascinating works.

The following day began with sessions, and after lunch, participants split into different groups. The Startup & Partner Pavilion, led by @Evgeny Shvarov, was a highlight, showcasing the InterSystems ecosystem. Great discussions, innovative ideas, and new connections emerged throughout these exchanges, with the President and Vice President of InterSystems present, along with many other speakers and participants.

Another highlight of READY for the Developer Community was the workshop I had the pleasure of leading: “Full Stack with InterSystems IRIS – building an end-to-end IT architecture.” Through a hands-on tutorial, participants explored how InterSystems IRIS can serve as the backbone of a complete, end-to-end IT architecture.

The session sparked many questions, discussions, and exchanges, before concluding in a friendly atmosphere with a Kahoot game. I was delighted to see that one of the winners was discovering InterSystems IRIS for the very first time during this workshop, alongside @Ward De Backer and @Lorenzo Scalese, who also won prizes.

And that’s a wrap for this READY. A huge thank you to all the participants, speakers, partners, and, of course, the organizers for making this edition such a success!

Comentarios (0)1
Inicie sesión o regístrese para continuar
Artículo
· 16 hr atrás Lectura de 3 min

Le retour sur France & Benelux READY 2026

Le France & Benelux READY 2026 vient de s’achever, et ces deux journées ont une nouvelle fois démontré à quel point la Communauté des Développeurs est dynamique, curieuse et engagée. Voici un retour en images et en mots sur cette belle édition.

L’événement a débuté par les welcome remarks de @Adeline Icard et @Geoffroy Vitoux, donnant le ton pour les journées à venir : innovation, partage et collaboration.

@Don Woodlock est ensuite intervenu pour une présentation inspirante sur les valeurs et la culture d’InterSystems, un moment fort qui a particulièrement résonné auprès des participants.

Les premières sessions ont immédiatement plongé les participants dans des sujets concrets et inspirants, avec des échanges riches autour des technologies InterSystems et de leurs usages.

Tout au long du READY, nous avons eu le plaisir de retrouver de nombreux participants pendant les sessions.

Les questions, discussions et retours d’expérience ont mis en évidence un fort intérêt pour des sujets pratiques et orientés terrain, que ce soit du point de vue du développeur, de l’architecte ou du manager. J’ai eu la chance de capturer un moment avec @Adeline Icard, l’une des organisatrices de l’événement.

Le dîner de gala a été l’occasion de prolonger les échanges dans un cadre plus détendu. Michel Amous a ouvert la soirée avec un très beau discours.

Le cadre était tout simplement exceptionnel : le restaurant Les Ombres du chef Alain Ducasse, offrant une vue spectaculaire sur la tour Eiffel.

Avec @Anastasia Dyubaylo et @Evgeny Shvarov.

Plus tard dans la soirée, @Adeline Icard a présenté la soprano Laure Poissonnier, qui nous a enchantés par sa performance.

Comme c’est la tradition lors de ces événements, nous avons également profité d’une visite de la collection permanente du musée du quai Branly, et découvert des œuvres particulièrement intéressantes.

La journée suivante a commencé par des sessions, puis après le déjeuner, les participants se sont répartis en différents groupes. Le Startup & Partner Pavilion, animé par @Evgeny Shvarov, a été un moment fort, mettant en lumière l’écosystème autour d’InterSystems. De belles discussions, des idées innovantes et de nouvelles connexions se sont nouées tout au long de ces échanges, en présence du Président et du Vice-Président d’InterSystems, parmi d'autres intervenants et participants.

Un autre temps fort du READY pour la Communauté des Développeurs a été le workshop que j’ai eu le plaisir d’animer: “Full Stack with InterSystems IRIS – building an end-to-end IT architecture”. À travers un tutoriel pratique, les participants ont exploré comment InterSystems IRIS peut servir de socle à une architecture IT complète, de bout en bout.

La session a donné lieu à de nombreuses questions, discussions et échanges à la fin, avant de se conclure dans une ambiance conviviale par un Kahoot. J’ai eu le plaisir de constater que l’un des gagnants découvrait InterSystems IRIS pour la toute première fois lors de ce workshop, aux côtés de @Ward De Backer et @Lorenzo Scalese, qui ont également remporté des lots.

Et voilà pour ce READY. Un grand merci à tous les participants, les speakers, les partenaires et, bien sûr, aux organisateurs pour cette édition réussie!

Comentarios (0)1
Inicie sesión o regístrese para continuar
Artículo
· 20 hr atrás Lectura de 5 min

JSON2Class, o conversor de JSON para ObjectScript que você sempre quis

Quantas vezes você teve que receber ou gerar um JSON e desejou poder trabalhar nele usando DTLs sem ter que lidar com DynamicObjects tentando lembrar o nome de cada campo? Você quer dividir e tornar seu arquivo JSON gigante mais digerível?

No meu caso, nunca, mas pensei que alguém poderia achar útil ter um recurso que captura seu JSON e o divide em uma série de classes ObjectScript com as quais você pode trabalhar de forma mais fácil e conveniente.

Pois bem... contemplem o JSON2Class em toda a sua glória!

Como o JSON2Class funciona?

É muito simples: ele aproveita os recursos do Embedded Python para fatiar e analisar seu JSON e gerar as classes associadas. Essas classes geradas serão de dois tipos:

  • %Persistent: para a classe principal ou raiz.
  • %SerialObject: para todas as subclasses que serão anexadas à principal.

Para fazer isso, ele leva em consideração os seguintes pontos:

Palavras reservadas

Nem todo nome de propriedade que vem no seu JSON é aceitável, então ele será modificado adicionando ao final do nome JSON, de modo que " language" se tornará " languageJSON".

Caracteres especiais

Caracteres especiais como "_" também são  removidos, então "patient_name" passará a ser chamado de "patientname".

%JSONFIELDNAME

Para evitar que a classe mude de nome quando for convertida de volta para JSON, o atributo %JSONFIELDNAME foi adicionado às propriedades cujos nomes são modificados, permitindo manter o rótulo original ao exportá-lo para JSON.

Gerando as classes

Toda a funcionalidade está contida na classe Utils.JSON2Class  , e para invocar o processo de geração temos o seguinte método:

ClassMethod Convert(
    json As %String,
    basePackage As %String = "App.Model",
    rootClassName As %String = "Root",
    outDir As %String = "/shared/generated"
) As %String

Vamos analisar os atributos do ClassMethod:

  • json: Este será nosso JSON modelo que queremos gerar.
  • basePackage: O pacote no qual todas as classes serão implementadas.
  • rootClassName: O nome da classe persistente que atuará como a raiz.
  • outDir: O diretório local onde os arquivos de classe serão gerados.

Exemplo:

Começamos com um JSON típico, como um recurso FHIR do tipo patient:

{
	"resourceType": "Patient",
	"id": "example",
	"identifier": [
		{
			"use": "usual",
			"type": {
				"coding": [
					{
						"system": "http://terminology.hl7.org/CodeSystem/v2-0203",
						"code": "MR"
					}
				]
			},
			"system": "urn:oid:1.2.36.146.595.217.0.1",
			"value": "12345",
			"period": {
				"start": "2001-05-06"
			},
			"assigner": {
				"display": "Acme Healthcare"
			}
		}
	],
	"active": true,
	"name": [
		{
			"use": "official",
			"family": "Chalmers",
			"given": [
				"Peter",
				"James"
			]
		},
		{
			"use": "usual",
			"given": [
				"Jim"
			]
		},
		{
			"use": "maiden",
			"family": "Windsor",
			"given": [
				"Peter",
				"James"
			],
			"period": {
				"end": "2002"
			}
		}
	],
	"telecom": [
		{
			"use": "home"
		},
		{
			"system": "phone",
			"value": "(03) 5555 6473",
			"use": "work",
			"rank": 1
		},
		{
			"system": "phone",
			"value": "(03) 3410 5613",
			"use": "mobile",
			"rank": 2
		},
		{
			"system": "phone",
			"value": "(03) 5555 8834",
			"use": "old",
			"period": {
				"end": "2014"
			}
		}
	],
	"gender": "male",
	"birthDate": "1974-12-25",
	"_birthDate": {
		"extension": [
			{
				"url": "http://hl7.org/fhir/StructureDefinition/patient-birthTime",
				"valueDateTime": "1974-12-25T14:35:45-05:00"
			}
		]
	},
	"deceasedBoolean": false,
	"address": [
		{
			"use": "home",
			"type": "both",
			"text": "534 Erewhon St\nPeasantVille, Rainbow, Vic3999",
			"line": [
				"534 Erewhon St"
			],
			"city": "PleasantVille",
			"district": "Rainbow",
			"state": "Vic",
			"postalCode": "3999",
			"period": {
				"start": "1974-12-25"
			}
		}
	],
	"contact": [
		{
			"relationship": [
				{
					"coding": [
						{
							"system": "http://terminology.hl7.org/CodeSystem/v2-0131",
							"code": "N"
						}
					]
				}
			],
			"name": {
				"family": "du Marché",
				"_family": {
					"extension": [
						{
							"url": "http://hl7.org/fhir/StructureDefinition/humanname-own-prefix",
							"valueString": "VV"
						}
					]
				},
				"given": [
					"Bénédicte"
				]
			},
			"additionalName": [
				{
					"use": "nickname",
					"given": [
						"Béné"
					]
				}
			],
			"telecom": [
				{
					"system": "phone",
					"value": "+33 (237) 998327"
				}
			],
			"address": {
				"use": "home",
				"type": "both",
				"line": [
					"534 Erewhon St"
				],
				"city": "PleasantVille",
				"district": "Rainbow",
				"state": "Vic",
				"postalCode": "3999",
				"period": {
					"start": "1974-12-25"
				}
			},
			"additionalAddress": [
				{
					"use": "work",
					"line": [
						"123 Smart St"
					],
					"city": "PleasantVille",
					"state": "Vic",
					"postalCode": "3999"
				}
			],
			"gender": "female",
			"period": {
				"start": "2012"
			}
		}
	],
	"managingOrganization": {
		"reference": "Organization/1"
	}
}

Vamos agora olhar para o objeto Root, que será nossa classe principal de paciente:

Vamos agora olhar para o objeto Root, que será nossa classe principal de paciente:

Class App.Model.Root Extends (%Persistent, %JSON.Adaptor)
{

Property resourceType As %String;
Property idJSON As %String(%JSONFIELDNAME = "id");
Property identifier As list Of App.Model.Root.Identifier;
Property active As %Boolean;
Property name As list Of App.Model.Root.Name;
Property telecom As list Of App.Model.Root.Telecom;
Property gender As %String;
Property birthDate As %String;
Property deceasedBoolean As %Boolean;
Property address As list Of App.Model.Root.Address;
Property contact As list Of App.Model.Root.Contact;
Property managingOrganization As App.Model.Root.ManagingOrganization;
}

Et voilà! Agora podemos armazenar nosso JSON como um objeto regular.

Próximos passos

Não é ruim poder gerar automaticamente as classes, mas seria interessante poder transformar automaticamente o JSON em uma instância das classes que criamos, levando em conta as particularidades dos nomes das propriedades.

1 nuevo comentario
Comentarios (1)2
Inicie sesión o regístrese para continuar
Artículo
· 20 hr atrás Lectura de 11 min

IKO Plus: HSSYS Mirroring with IKO

Enabling HSSYS Mirroring Out of the Gate with IKO

For those of us building InterSystems workloads on Kubernetes, we are definitely spoiled with the InterSystems Kubernetes Operator (IKO) doing the heavy lifting and mirroring on day one.  Where us spoiled brats jump up and down is when we try to add additional databases/namespaces when we provision from HealthConnect containers on day two, while others get to utilize HealthShare Mirroring for this task, the prerequisite of mirroring HSSYS out of the gate has been somewhat elusive.  Here is example on how you can this powerful feature up and running with the employment of IKO and IrisClusters.

HealthCare Mirroring

The documentation for this feature is great and highlights the functionally of what its protecting etc, but it misses bragging about the magical operational add it provides.  What it means for those automating workloads is that once you mirror HSSYS, any subsequent namspace provisioned after it gets automatically mirrored for free.

The documentation provides a process of which to set it up, which is manual in nature, that we need to automate to have IKO carry it out, which is great.

https://docs.intersystems.com/healthconnect20253/csp/docbook/Doc.View.cl...


The top three things that need to happen:

  • Mirror HSSYS
  • Schedule the Mirroring Agent
  • Use the Installer Wizard to create a Foundation namespace on primary

Enabling IKO Features

The bits and pieces of functionality we exploited to get this work.

  • iko seeding
  • iris-main --after operations

I wrote up seeding pretty good in a previous post:

https://community.intersystems.com/post/iko-plus-database-management-mig...

But something I like that we have been taking advantage of is the --before and --after flags in the iris-main `args`. 

          args:
          - --before
          - /usr/bin/bash /hs/before/before.sh
          - --after
          - /usr/bin/bash /hs/after/after.sh

These are configmaps that are mounted as scripts and execute as their label indicates.

before.sh - iris is not available here, good for grabbing stuff, oras operations possibly, file system stuff, whatever.

after.sh - iris is available here, run cos code, import ipm packages, spin sugar.
 

1️⃣ Mirror

Obviously mirror this, but also declare a databases block as mirrored using a seed from the container location of the database.

    data:
      irisDatabases:
      - directory: /irissys/data/IRIS/mgr/hssys
        mirrored: true
        name: HSSYS
        seed: /usr/irissys/mgr/hssys/
      mirrorMap: primary,backup
      mirrored: true

2️⃣ initContainer

Now, the upcoming yaml slingers will say this is a task for an agent or the operator itself, but is emulating the manual task for provisioning HSSYS as a mirror. 

Add a volume and a volumeMount for the shared volume for the init container ...

      volumeMounts:
      - mountPath: /hs/before/
        name: ikoplus-before-volume
      - mountPath: /hs/after/
        name: ikoplus-after-volume
      - name: hssys-volume
        mountPath: /hssys

...and the initContainer itself.

          initContainers:
            - name: hssys-copy
              image: alpine:3.19
              env:
                - name: POD_NAME
                  valueFrom:
                    fieldRef:
                      fieldPath: metadata.name
              command: ["/bin/sh", "-c"]
              args:
                - |
                  set -euo pipefail

                  # Install deps: tar + kubectl
                  apk add --no-cache tar curl ca-certificates >/dev/null
                  KUBECTL_VERSION="${KUBECTL_VERSION:-v1.29.0}"
                  curl -fsSL -o /usr/local/bin/kubectl "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl"
                  chmod +x /usr/local/bin/kubectl

                  if [ "$POD_NAME" = "{{ $.Release.Name }}-hssys-data-0-1" ]; then
                    echo "Hostname match; performing pod-to-pod hssys copy..."
                    kubectl cp -n {{ .Release.Namespace }} {{ $.Release.Name }}-hssys-data-0-0:/irissys/data/IRIS/mgr/hssys/IRIS.DAT /hssys/IRIS.DAT
                    echo "Copy complete."
                  else
                    echo "Hostname does not match; skipping copy."
                  fi
              securityContext:
                runAsUser: 0 # run as root
                runAsNonRoot: false
                readOnlyRootFilesystem: false
              volumeMounts:
              - name: hssys-volume
                mountPath: /hssys

Its quite simple and only runs the script in the initi container if its running on the backup at start.  This takes the mirrored version of hssys/IRIS.DAT and pops it on the backup in /hssys/IRIS.DAT. 

3️⃣ The after.sh party 🎉

Almost verbatim to the manual steps: 

  • Unmount
  • Copy
  • Mount
  • Activate
  • CatchUp
  • Schedule Task

... only do this once, and only do this on the backup at provision time.

--- 
apiVersion: v1
data:
  after.sh: |-
    #!/usr/bin/bash

    if ! [ -f "/irissys/data/after.done" ]; then
      echo "{{ $.Release.Name }} After Script..."
      if [[ "$(hostname)" == "{{ $.Release.Name }}-hssys-data-0-1" ]]; then
        echo "After for mirror b only..."
        iris session IRIS <<'EOF'
    zn "%SYS"
    w ##class(SYS.Database).%OpenId("/irissys/data/IRIS/mgr/hssys/").Dismount()
    Set sc = ##class(%File).CopyFile("/hssys/IRIS.DAT", "/irissys/data/IRIS/mgr/hssys/IRIS.DAT", 1)
    w ##class(SYS.Database).%OpenId("/irissys/data/IRIS/mgr/hssys/").Mount()
    SET sc = ##class(SYS.Mirror).ActivateMirroredDatabase("/irissys/data/IRIS/mgr/hssys/")
    Set db=##class(SYS.Database).%OpenId("/irissys/data/IRIS/mgr/hssys/")
    set SFNlist = $LISTBUILD(db.SFN)
    SET sc = ##class(SYS.Mirror).CatchupDB(SFNlist)
    Halt
    EOF
      fi

      iris session IRIS <<'EOF'
    zn "%SYS"
    set tSC=##Class(Security.Users).Create("ikoplus","%All","ikoplus","HSSYS","","","",0,1,,,,,,1,1)
    zn "HSLIB"
    do ##class(HS.Util.Mirror.Task).Schedule("HSSYS")
    Halt
    EOF

      touch "/irissys/data/after.done"
    fi

    exit 0

Note the service account is needed in the data pod to exec across IrisClusters, you will see that in the reference IrisCluster below.

Reference IrisCluster

Ill paste this here, but I ran it as chart so the Helm tags are resident, but adapt it to your own use or put on a pair of helm glasses.  The things you do not see here are the secrets, which are the container pull secrets/licenses, but the rest is there including the applicable service account with rootabega on the cluster to exec across pods.

 
iriscluster-hssys.yaml

I named the namespace after @Eduard Lebedyuk who afforded me some banter trying to figure this one out.

kubectl create ns eduard
helm install ikoplus14 .

Flow

So the dev story for the order of things is this:

IKO gets put into motion through the admission hook to create a mirrored HealthConnect deployment, which is a pair of IrisClusters and an arbiter.  The Primary comes up with the instruction to create HSSYS from a seed in the container, then a bit of ugliness occurs, but nobody sees it except us, or observability if they are pushing logs.

If you were to freeze frame at this moment, the state would look a little bit like:

 
Ugly

Its inside a teaser because well, its ugly, and the ugliness occurs on both primary and backup on creation.

However, after.sh backup comes up, it takes care of all of that, but copying over HSSYS, activating, catching things up and covers it up like an Epstein file in a public bucket.

Attestation

Now shell into your active primary, and create 5 databases using the installer.

For i=1:1:5 { Set ns = "OMOP"_i Do ##class(HS.Util.Installer.Foundation).Install(ns) }

Now sit back and relax, as the task fires every 5 minutes out of the box and the installer chugs a bit in the loop, inspecting on the backup member you should see the mirrored databases being created, activated, and caught up one by one, for free.

Addtionally, there is a ui to see how hard the mirroring agent is working and what its been up to.  Here you can see the last action was class mappings... if you have every watched the installer do its thing in the ui or from the backend, that is definitely the latest of the operations.

Comentarios (0)1
Inicie sesión o regístrese para continuar
Anuncio
· 4 feb, 2026

ObjectScript 開発の未来を、共に形づくりませんか?

開発者の皆さん、こんにちは!

次世代の ObjectScript 開発ツールを形づくるための取り組みに、皆さまのご参加をお待ちしています。IRIS開発者向けに特別に設計された、AIを活用したObjectScript コーディングアシスタントの開発に取り組んでいます。

ObjectScript 向けに適応された汎用的な AI ではなく、ObjectScript のイディオム、IRIS API、interoperability  プロダクション、そして実際の開発者ワークフローを理解するためにゼロから構築されたソリューションです。

本当に役立つものを作るために、皆さまのご意見をぜひお聞かせください。

👉 ObjectScript Coder Agent 開発者アンケート(英語) 👈

アンケートは約5分程度の内容で、次のような質問に回答いただきます。

  • あなたの役割と経験レベル
  • 現在の問題点とワークフロー
  • 最も重要な機能(コード生成、デバッグ、学習サポートなど)
  • このようなツールをどこでどのように使いたいか

この調査は、ObjectScript の経験レベルを問わず、あらゆる開発者の方が対象となります。

What’s next?

  • 集計結果はコミュニティと共有されます。
  • ご関心のある方には、早期ベータ版への招待を行う場合があります。
  • 開発の進捗に応じて、定期的に最新情報をお知らせします

皆さまからのフィードバックは、開発の優先順位や機能の方向性に反映されます。

ご不明な点などございましたら返信欄へのコメント、または thomas.dyar@intersystems.com まで直接ご連絡ください。

ObjectScript コミュニティのためのツールづくりにご協力いただき、ありがとうございます。皆様からのご意見をお待ちしております!

Comentarios (0)1
Inicie sesión o regístrese para continuar