Nouvelle publication

Rechercher

Article
· Sept 22, 2024 1m de lecture

SMART on FHIR app - Sample with Hands-on Exercise/Workshop Instructions

Based on a great sample and workshop built by @Luis Angel Pérez Ramos (see related articles and related Open Exchange app), which included a local InterSystems IRIS for Health container (and desired setup), this sample presented here, adapted the workshop for using the InterSystems Cloud FHIR Server, and it's related setup.

The related Open Exchange and GitHub repo included detailed instructions (and related screenshots) to create the desired project and flow.

See this series of short videos to accompany the steps to be performed.

Basically the steps include:

  • Setting up a Cloud FHIR Server [video]
  • Setting up an OAuth Server (auth0 by Okta) [video]
    • Creating an Application
    • Creating an API
    • Creating a User
  • Configuring the FHIR Server [video]
    • Creating an OAuth Server
    • Creating an Application
  • Adapting the app (Angular) to point to FHIR and OAuth Servers [video]
    • Adapting proxy.config.json
    • Adapting nginx.conf
    • Adapting app.module.ts
  • Testing running the app [video]
    • Examining the Login behind the scenes
    • Examining fetching and updating data behind the scenes

Enjoy!

3 Comments
Discussion (3)2
Connectez-vous ou inscrivez-vous pour continuer
Question
· Sept 19, 2024

Input Redirection

Hello, I try to develop a REST interface where I need to interact with legacy MUMPS routines. How can I pass in input to a Read without modifying the legacy code?

I think in linux I can execute command < inputfile to read from file, but how does it work in ObjectScript?

7 Comments
Discussion (7)5
Connectez-vous ou inscrivez-vous pour continuer
Article
· Sept 19, 2024 6m de lecture

eBPF - Cilium on FHIR® - A Star Wars Story

 

Anakin Skywalker challenged the high ground and has been terribly injured on Mustafar.  

 
He is a relatively new employee of the Galatic Empire, covered by a Large Group Planetary Plan and now has an active encounter in progress for emergent medical services in the Grand Medical Facility on Coruscant. The EMR deployed for the Galactic Health System is Powered by InterSystems FHIR Server running on Kubernetes protected by Cilium.

Let's recreate the technical landscape, to be performed in the style of Isovalent Labs...

Kind Cluster

Lets fire up a 3 node cluster, and disable the CNI so we can replace it with Cilium. 

cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
  - role: worker
  - role: worker
  - role: worker
networking:
  disableDefaultCNI: true
EOF

This will provision the kind cluster, 3 nodes wide with a single control plane.


Cilium

Cilium is an open-source project that provides networking, security, and observability for containerized environments like Kubernetes clusters. It uses a Linux kernel technology called eBPF (extended Berkeley Packet Filter) to inject security, networking, and observability logic into the kernel.

In other words, wields the force.

cilium install --version v1.16.0
cilium status --wait


Hubble

Hubble is a clown suit for Cilium, providing ridiculous visibility to what powers Cilium are in play in real time.

cilium enable hubble

 

 

InterSystems FHIR Workload

InterSystems is the GOAT of interoperability, and transforms Healthcare Data like a protocol Droid.

kubectl apply -f https://raw.githubusercontent.com/sween/basenube/main/scenarios/ciliumfhir/deploy/cilium-fhir-starwars.yaml

The resulting workload has 4 deployments:

GrandMedicalFacility


Integrated Delivery Network based in Coruscant, with facilities as far as the Outer Rim, runs Epic and utilizes InterSystems I4H as a FHIR Server.

MedicalDroid FX-6


This 1.83-meter-tall droid supplied Vader with a blood transfusion and trained in cybernetic legs procedures.

MedicalDroid DD-13


Also known as the DD-13 tripedal medical droid, this droid has three legs for stability and was designed to install cybernetic implants. 

MedicalDroid 2-1B


2-1B droids have hypodermic injectors and precision-crafted servogrip pincers, and can be upgraded to specialize in areas like cybernetic limb replacement, neurosurgery, and alien biology.

Since we will need it anyway for upcoming interviews, lets tell the story in true STAR (Sithuation, Task, Action, Result) methodology.

Sith-uation

Palpatine accompanied the fallen jedi to the facility, and upon arrival helped registration admit him as Darth Vader.  

cat > vader.json << 'EOF'
{
  "name": [
    {
      "use": "official",
      "family": "Vader",
      "given": [
        "Darth"
      ]
    }
  ],
  "gender": "male",
  "id": "DarthVader",
  "birthDate": "1977-05-25",
  "resourceType": "Patient"
}
EOF
curl -v -X PUT \
  -H "Content-Type: application/fhir+json" \
  -d @vader.json \
  "http://coruscanthealth:52773/intersystems/fhir/r5/Patient/DarthVader"

Darth Vader is now registered, and can be seen throughout the Health System...  

Galactic IT Outage

There is a problem though!  

Shortly after registration, a Galactic IT Outage has occured, making the Identity Provider for the Health System unavailable. The InterSystems FHIR Resource Server is SMART enabled, and the IDP is casters up, making EMR launches impossible with the absence of the jwt token with the applicable scopes to protect the routes.



Sure as Bantha Fodder, we definitely have a problem... the care team cannot access the patient record, nothing but 401's and 403's and were not talking about your Galactic Retirement Plan.

Although the Hubble UI only provides a hint to what is going on, Inspecting the Hubble flows with Layer 7 information reveals the sithuation.





...and after adding some debugs bunny to the InterSystems FHIR endpoint, confirms it.

 
FHIR Debug
zw^FSLOG
...
^FSLOG(379555)="DispatchRequest^HS.FHIRServer.Service^944|Msg|Dispatch interaction read for Patient/DarthVader|09/19/2024 10:48:20.833339AM"
^FSLOG(379556)="DispatchRequest^HS.FHIRServer.Service^944|Msg|Request Completed in .000186 secs: Patient/DarthVader|09/19/2024 10:48:20.833450AM"
^FSLOG(379557)="processRequest^HS.FHIRServer.RestHandler^944|Msg|Response Status: 401, Json: Patient|09/19/2024 10:48:20.833454AM"
...


Task

What's a great line from Star Wars that doesn't get quoted enough? :  r/StarWarsCantina

Action

With the route enforcement from SMART not applicable, lets do this our way and use Cilium to protect the endpoints while Vader gets immediate attention the Emperor demands.  We will go Rogue One here on the cluster and hand off the endpoint/route protection to Cilium while the Galaxy figures itself out from the outage.

Lets institute a deny all, from everywhere, with a CiliumClusterwideNetworkPolicy, and work backwards zero trust style.
 

cat <<EOF | kubectl apply -n galactic-fhir -f- 
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: "denyall-coruscanthealth"
spec:
  description: "Block all the traffic (except DNS) by default"
  egress:
  - toEndpoints:
    - matchLabels:
        io.kubernetes.pod.namespace: kube-system
        k8s-app: kube-dns
    toPorts:
    - ports:
      - port: '53'
        protocol: UDP
      rules:
        dns:
        - matchPattern: '*'
  endpointSelector:
    matchExpressions:
    - key: io.kubernetes.pod.namespace
      operator: NotIn
      values:
      - kube-system
EOF

Looking good, Cilium dropping it like its hot!



Now, lets open up the FHIR endpoint on the intersystems pod, disabling the oauth2 client.

set app = "/intersystems/fhir/r5"
Set strategy = ##class(HS.FHIRServer.API.InteractionsStrategy).GetStrategyForEndpoint(app)
// 7 = Mass Openness
Set configData.DebugMode = 7
Set configData = strategy.GetServiceConfigData()
Do strategy.SaveServiceConfigData(configData)

Lastly, lets create a CiliumNetworkPolicy to allow anybody from the org:empire, access to the route for DarthVaders record in the galactic-fhir namespace.

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "l7-visibility"
spec:
  endpointSelector:
    matchLabels:
      org: empire
  egress:
  - toPorts:
    - ports:
      - port: "53"
        protocol: ANY
      rules:
        dns:
        - matchPattern: "*"
  - toEndpoints:
    - matchLabels:
        "k8s:io.kubernetes.pod.namespace": galactic-fhir
    toPorts:
    - ports:
      - port: "52773"
        protocol: TCP
      rules:
        http:
          - method: "GET"
            path: "/intersystems/fhir/r5/Patient/DarthVader"
          - method: "HEAD"
            path: "/intersystems/fhir/r5/Patient/DarthVader"
EOF

Looks like we may be able to get back to iRacing, I think we are good.



...except

 

Yeah, looks like the payer is getting dropped...



Policy verdict = DROPPED



Let's add another policy, allowing org:payer access to Vaders route:

 

cat <<EOF | kubectl apply -n galactic-fhir -f- 
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "l7-visibility-payer"
spec:
  endpointSelector:
    matchLabels:
      org: payer
  egress:
  - toPorts:
    - ports:
      - port: "53"
        protocol: ANY
      rules:
        dns:
        - matchPattern: "*"
  - toEndpoints:
    - matchLabels:
        "k8s:io.kubernetes.pod.namespace": galactic-fhir
    toPorts:
    - ports:
      - port: "52773"
        protocol: TCP
      rules:
        http:
          - method: "GET"
            path: "/intersystems/fhir/r5/Patient/DarthVader"
          - method: "HEAD"
            path: "/intersystems/fhir/r5/Patient/DarthVader"
EOF

Welp, that did not quite cut it, and we can see why.



 

So we gave the payer a call and told them to access the "correct" patient record, and Anakin Vader gets his legs.

Rant time...




Result

1 Comment
Discussion (1)1
Connectez-vous ou inscrivez-vous pour continuer
Annonce
· Sept 16, 2024

第2回 開発者コミュニティ・ミートアップ Python ワークショップの事前準備について

※ 本内容は随時更新予定です。ワークショップに必要な内容をご覧いただき、参加のご検討などしていただければ幸いです。

Pythonワークショップにご参加いただく場合は、事前に以下の環境をご用意ください。

  • IRIS 2024.1.1 for Windows Community Edition (※ これからダウンロードされる方は、バージョンが異なりますので下記コメントをご確認ください)
    • キットダウンロードはこちらの記事をご覧ください。
    • インストールオプションはデフォルト (インストールタイプ: 開発、初期セキュリティ設定: 最小)
  • Visual Studio Code (任意のバージョン) と ObjectScript用エクステンション
    • エクステンションのインストール方法はこちらの記事をご覧ください。
  • 以下のPythonライブラリを irispip (<IRISインストールディレクトリ\bin\irispip.exe) でインストール
    • flask, nicegui, sqlalchemy-iris,  scikit-learn,  numpy, pandas
8 Comments
Discussion (8)2
Connectez-vous ou inscrivez-vous pour continuer
Article
· Sept 15, 2024 3m de lecture

Comment trouver mon texte spécifique en ObjectScript

Vous connaissez probablement cette situation :
il y a quelque temps, vous avez trouvé une fonction $ZU très spéciale pour
un type de problème spécifique. Une sorte de formule mystique.
Elle est devenue populaire et a été utilisée par de nombreux programmeurs
dans tout votre code et toutes vos installations .

Plusieurs versions et updates plus tard, vous êtes informé par ISC que
votre $ZU mystique est déprécié et n'est plus supporté. Et on vous conseille
de le remplacer par un nouveau $something(). 

Alors, comment trouver et documenter l'utilisation de votre code mystère ?
Il pourrait se trouver dans les classes, dans le code MAC,  INT, INC.
Et il peut être distribué dans plusieurs namespaces.
Dans le passé, Studio n'était encore completé et peu adapté, mais lent et peu précis.

J'ai rencontré cette situation plus d'une fois dans différentes installations.
Source Control n'était pas disponible à l'époque
et n'a été que rarement utilisé lorsqu'il a été ajouté.

ObjectScript étant le seul choix possible pour relever ce défi, j'ai écrit mon propre outility.
Ma solution s'est développée au fil des ans et une fois que la migration vers IRIS a été planifiée,
j'ai vérifié une fois de plus à quel point elle était utile.
Et comme elle était écrite en ObjectScript pur, elle fonctionnait dans IRIS sans qu'aucun
caractère n'ait été modifié. Comme vous le savez peut-être, le problème de la recherche
d'un morceau de texte spécifique en ObjectScript n'a pas changé. 

Mon objectif personnel pour mon outility était

  • uniquement l'ObjectScript
  • pas de constructions fantaisistes, miraculeuses ou délicates
  • le moins possible de fonctions $advanced
  • préférer la lisibilité à l'élégance en faveur de la maintenance future
  • présenter le nombre d'occurrences comptées par espace de noms et par élément de code
  • pour les classes, diviser également 
    • parameter,
    • properties (si calculated)
    • methods
    • indices
  • une option pour montrer la ligne qui les contient
  • ne se soucient pas de la liste.
    • N'importe quel programme de terminal peut écrire un journal
    •  bash a son STDOUT à cet effet

Ce utility est donc disponible pour vous sur Open Exchange et GitHub
J'ai également créé une vidéo pour démontrer le péage en action.
Et il est également disponible sur Demo Server

Il vous suffit de démarrer depuis le terminal
user>DO ^rcc.find 

Et vous obtenez quelques questions

  •  quel est le texte que vous recherchez ?
  • verbose » ?
    • voulez-vous voir chaque ligne complète contenant votre texte ?
    • Attention, cela peut devenir une liste assez énorme
    • Un test récent a trouvé plus de 90000 résultats.
    • Avec verbose=1, on obtient plus de 90000 lignes.
  • Uniquement en majuscules ?
    • Cela résout le problème selon lequel une fonction peut être écrite
    • en majuscules, minuscules ou mixtes.
    • "Uppercase=1" garantit que vous ne manquez aucune occurrence
  • Quel type de code voulez-vous vérifier ? (CLS,MAC,INT,INC,ALL)
  • Quel namespace voulez-vous rechercher ?
    • Un namespace spécifique de votre liste ou ALL
    • pour ALL vous obtenez une liste condensée d'espaces de noms et de types
    • (non visible dans la vidéo)

La sélection de namespace lance la recherche.
Alors on danse !

USER>do ^rcc.find
----------------
 
enter search string [$ZU] <blank> to exit: RCC
          Verbose? (0,1) [0]:
          Force UpperCase? (1,0) [1]:
 
enter code type (CLS,MAC,INT,INC,ALL) [ALL]: CLS
 
select namespace (ALL,%SYS,DOCBOOK,ENSDEMO,ENSEMBLE,SAMPLES,USER) [USER]:
 
** Scan Namespace: USER **
 
** CLS **
** 2      User.ConLoad
** 15     User.Main
** 3      csp.form
** 3      csp.winner
** 2      dc.rcc.Contest
** 37     dc.rcc.Main
** 1      dc.rcc.Prize
** 63 CLS **
----------------

 

J'espère que vous avez apprécié mon histoire.
J'ai essayé d'éviter les séquences de code ennuyeuses. Il y a OpenExchange et Github pour cela.

Et s'il vous plaît, excusez mon français rouillé.
Je l'ai appris à l'école il y a 65 ans et il n'y était pas question de technologie
mais de Molière, Sartre, Queffélec, Anouilh, Ionesco, ... 

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer