Hi, I want to automate a menu based program for which I don't have the source
If I run it interactively I do this: do ^<program>
It presents a menu and then you can go down further menus
Based on the selection it may ask for answers to other questions.
Is there some way I give the program a "response" file?
If not would I be able to use I/O redirection for this task? Inputs would come from a file. Output should go to the terminal (so I monitor how far the process has gone)
I have seen some examples of redirection code and it seems quite complicated.
This is a demo of how to add unit tests to an IRIS application using the InterSystems Package Manager. Covered are how to create new unit tests, the Package Manager commands to run tests, and how to track code coverage statistics using the ObjectScript TestCoverage package.
🗣 Presenter: @Pravin Barton, Principal Applications Developer, InterSystems
L'utilisation de Embedded Python lors de la création d'une solution basée sur InterSystems peut ajouter des fonctionnalités très puissantes et approfondies à votre boîte à outils.
J'aimerais partager un exemple de cas d'utilisation que j'ai rencontré : l'activation d'un CDC (Change Data Capture) pour une collection mongoDB - la capture de ces modifications, leur digestion via un flux d'interopérabilité et, pour finir, la mise à jour d'un EMR via une API REST.
La fonctionnalité principale – « Observation des changements » 👀
L'idée de base est d'utiliser le package PyMongo, qui, entre autres, permet de suivre les modifications au sein d'une base de données mongo via son change_streams.
La partie importante se trouve dans l'adaptateur entrant que j'ai créé et qui possède une méthode OnInit() qui inclut cette ligne :
J'utilise la méthode watch() ici pour surveiller les changements d'une collection spécifique dans une base de données.
Je les ai définis via les paramètres du service métier :
Ensuite, dans la méthode OnTask(), j'utilise ceci pour capturer les modifications :
while self.changeStream.alive:
change = self.changeStream.try_next()
if change isnotNone:
Ici, j'utilise la propriété alive et la méthode try_next() pour obtenir les détails des modifications survenues.
Pour chaque modification, je crée un objet IRIS Stream avec le contenu JSON et je l'envoie à la méthode ProcessInput() du service métier.
Dans le service métier, je crée une requête importée à partir du contenu JSON et je l'envoie au routeur.
Le flux général peut être illustré comme suit :
Voici une démonstration vidéo :
Quelques détails techniques supplémentaires 👩💻
Le service métier doit « masser » un peu le JSON car il inclut du JSON « flou », avant que je puisse autoriser son importation en tant que JSON valide.
Dans votre cas, vous pouvez soit modifier cela pour l'adapter à votre schéma, soit même envisager d'adapter mon exemple pour utiliser une approche plus « dynamique » où vous pouvez définir un paramètre qui serait utilisé pour importer dynamiquement le JSON vers un nom de classe variable (par rapport à mon nom codé en dur).
[Dans tous les cas, pour charger votre schéma JSON et créer une classe à partir de celui-ci, vous pouvez utiliser la classe Sample.OpenAPIClassGenerator que j'ai incluse dans mon exemple (adapté du générateur de classe de définition OpenAPI de @Guillaume Rongier (et appeler la méthode ProcessFile() que j'ai ajoutée sur votre fichier de schéma JSON).]
Il s’agit essentiellement de la partie principale de cette fonctionnalité : Adaptateur + Service métier qui envoie des messages avec les modifications apportées à une collection de bases de données Mongo.
Élargir le tableau 👩⚕️
À des fins de démonstration et pour créer un flux complet qui « raconte une histoire » (ce qui était le cas d'utilisation réel que j'avais), j'ai également ajouté une cible pour ce CDC, qui est une API REST d'un Dossier Patient Informatisé (DPI ou EMR pour Electronic Medical Record) fictif, qui prend les données des patients et les insère dans une table de patients.
Vous trouverez cette partie sous le package Demo.EMR (Data.Patient pour la table et Util.API pour l'API REST) ; et le package Demo.Int pour la partie Opérations métiers.
En fait, vous pouvez réutiliser cette partie pour tout autre besoin que vous pourriez rencontrer lorsque vous avez besoin d'une API fictive pour envoyer des données de patient à des fins de test en tant que destination cible.
[Notez que la table « Mock EMR » et l'API incluent des éléments de données que je n'ai pas utilisés dans cette démonstration, comme l'adresse e-mail et le numéro de téléphone]
Un exemple de flux complet (avec captures d'écran) 📷
Voici donc un exemple de déroulement de la manière dont cela fonctionne :
1. Ajoutez un document à votre collection mongo.
Commandes Shell (Docker exec pour se connecter au conteneur mongo et commandes mongosh pour lancer ReplicaSet et un document vers une collection)
$ docker exec -it mongo1 bash
root@e3b93abb5596:/# mongosh
Current Mongosh Log ID: 676708e5955c5e4448fe6910
Connecting to: mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.3.2
Using MongoDB: 6.0.19
Using Mongosh: 2.3.2
For mongosh info see: https://www.mongodb.com/docs/mongodb-shell/
test> use admin
switched to db admin
{ ok: 1 }
admin> db.auth("admin","admin123")
{ ok: 1 }
admin> rs.initiate()
{
info2: 'no configuration specified. Using a default configuration for the set',
me: '960427582b78:27017',
ok: 1
}
rs0 [direct: other] admin> use testDB
switched to db testDB
rs0 [direct: primary] testDB> db.testCol.insertOne({"mrn":"123456789","first_name":"john","last_name":"smith","dob":"2001-01-01","gender":"male"})
{
acknowledged: true,
insertedId: ObjectId('676714119af8c381e2fe6914')
}
Lorsque vous insérez le document, grâce au « watcher » exécuté dans IRIS, celui-ci se déclenchera dans l'adaptateur et le service métier
2. Examinez votre table « EMR » et voyez les nouvelles données de Mongo insérées dans celle-ci
DBeaver visualisant les données dans la table Patient
Avant les actions ci-dessus, notre table était vide (en utilisant DBeaver via JDBC pour se connecter à la base de données IRIS)
Et après, vous pouvez voir qu'un dossier patient a été ajouté avec les informations du document ajouté dans Mongo :
Bien sûr, vous pouvez utiliser des outils différents de DBeaver pour cet examen (y compris l'explorateur système du portail de gestion IRIS -> SQL), mais j'ai utilisé DBeaver pour jouer le rôle comme s'il s'agissait en effet d'un EMR externe et d'une table externe que nous regardons simplement via JDBC.
3. Examinez les « coulisses » d’InterSystems IRIS en prenant soin de ce flux
Trace visuelle du flux de messages
En regardant dans la trace visuelle d'interopérabilité InterSystems IRIS, vous pouvez voir les messages provenant du service métier qui a capturé le changement dans Mongo, via une transformation de données qui l'a transformé en message de demande envoyé à l'opération métier qui appelle l'API REST (qui met à jour la table des patients)
Looking in the InterSystems IRIS Interoperability Visual Trace you can see the messages flowing from the Business Service who captured the change in Mongo, via a Data Transformation that transformed it to the Request Message being sent to the Business Operation that calls the REST API (which updates the Patient Table)
Faites l'essai de votre côté🏎
L'application Open Exchange inclut tout le code associé et les instructions de configuration pour une démonstration complète basée sur le conteneur Docker comme indiqué ci-dessus (avec toutes les parties associées, y compris les conteneurs Mongo).
[Remarque : Mongo a une notion de ReplicaSet et c'est seulement avec cette fonctionnalité que change_streams fonctionne. Pour plus de simplicité, la démonstration ci-dessus suppose que mongo1 (il y a aussi mongo2 et mongo3) est le « principal »].
Encore une fois, ce n’est qu’un exemple de la manière dont Embedded Python peut vous permettre de relever vos défis d’interopérabilité très rapidement et facilement.