Salut la Communauté!
Profitez de regarder la nouvelle vidéo sur la chaîne Youtube d'InterSystems France.
📺 Utilisation de Business Process Designer dans InterSystems IRIS
InterSystems Ensemble Business Process Language (BPL) est un langage utilisé pour décrire des processus métier exécutables dans un document XML standard.
Salut la Communauté!
Profitez de regarder la nouvelle vidéo sur la chaîne Youtube d'InterSystems France.
📺 Utilisation de Business Process Designer dans InterSystems IRIS
Bonjour à tous,
En rendant un processus métier réutilisable, j'ai eu besoin de rendre la cible d'un <call> configurable en tant que paramètre de l'hôte métier. Cela peut se faire par indirection. Voici comment procéder :
L'intelligence artificielle (IA) attire beaucoup d'attention dernièrement car elle peut changer de nombreux domaines de nos vies. Une meilleure puissance informatique et plus de données ont aidé l'IA à réaliser des choses incroyables, comme l'amélioration des tests médicaux et la création de voitures autonomes. L'IA peut également aider les entreprises à prendre de meilleures décisions et à travailler plus efficacement, c'est pourquoi elle devient de plus en plus populaire et largement utilisée.
Bienvenue dans le prochain chapitre de ma série CI/CD, où nous discutons des approches possibles vers le développement de logiciels avec les technologies InterSystems et GitLab.
Aujourd'hui, parlons d'interopérabilité.
Lorsque vous avez une production d'interopérabilité active, vous avez deux flux de processus distincts : une production active qui traite les messages et un flux de processus CI/CD qui met à jour le code, la configuration de la production et les paramètres par défaut du système.
De toute évidence, le processus CI/CD affecte l'interopérabilité. Mais il y a des questions :
Commençons par le cycle de vie de la production.
Tout d'abord, la production peut être démarrée. Une seule production par espace de noms peut être lancée simultanément, et en général (à moins que vous ne sachiez vraiment ce que vous faites et pourquoi vous le faites), vous ne devrez lancer qu'une seule production par espace de noms, jamais. Il n'est pas recommandé de passer d'un espace de noms à l'autre entre deux ou plusieurs productions différentes. Le démarrage de la production démarre tous les Business Hosts activés définis dans la production. Le fait que certains Business Hosts ne démarrent pas n'affecte pas le démarrage de la production.
Conseils:
##class(Ens.Director).StartProduction("ProductionName")OnStart.Après le démarrage de la production, l'outil Ens.Director surveille en permanence la production en cours. Il existe deux états de production : état cible, défini dans la classe de production et les paramètres par défaut du système ; et état en cours d'exécution - les tâches en cours d'exécution avec les paramètres appliqués lors de la création des tâches. Si l'état souhaité et l'état actuel sont identiques, tout va bien, mais la production peut (et doit) être mise à jour s'il y a une différence. Habituellement, vous voyez cela sous la forme d'un bouton rouge "Mettre à jour" sur la page Configuration de la production dans le Portail de gestion du système.
La mise à jour de la production signifie une tentative pour que l'état de production actuel corresponde à l'état de production cible.
Lorsque vous exécutez ##class(Ens.Director).UpdateProduction(timeout=10, force=0) pour mettre à jour la production, il effectue les opérations suivantes pour chaque Business Host :
Après avoir exécuté cette opération pour chaque Business Host, UpdateProduction construit l'ensemble des changements :
Ensuite, il les applique.
De cette manière, la "mise à jour" des paramètres sans rien changer n'entraîne aucune interruption de la production.
Conseils:
##class(Ens.Director).UpdateProduction(timeout=10, force=0)Ens.Director:UpdateProduction avec un délai plus long.UpdateProduction NE MET PAS A JOUR les BHs dont le code est obsolète. C'est un comportement orienté vers la sécurité, mais si vous voulez mettre à jour automatiquement tous les BHs en cours d'exécution lorsque le code sous-jacent change, suivez les étapes suivantes :
First, load and compile like this:
do $system.OBJ.LoadDir(dir, "", .err, 1, .load)
do $system.OBJ.CompileList(load, "curk", .errCompile, .listCompiled)
Maintenant, listCompiled contiendrait tous les éléments qui ont été compilés (utilisez git diffs pour minimiser l'ensemble des éléments importés) à cause du marqueur u. Utilisez cette listCompiled pour obtenir un $lb de toutes les classes qui ont été compilées :
set classList = ""
set class = $o(listCompiled(""))
while class'="" {
set classList = classList _ $lb($p(class, ".", 1, *-1))
set class=$o(listCompiled(class))
}
Et ensuite, calculer une liste de BHs qui nécessitent un redémarrage :
SELECT %DLIST(Name) bhList
FROM Ens_Config.Item
WHERE 1=1
AND Enabled = 1
AND Production = :production
AND ClassName %INLIST :classList
Enfin, après avoir obtenu bhList, arrêtez et démarrez les hôtes affectés :
for stop = 1, 0 {
for i=1:1:$ll(bhList) {
set host = $lg(bhList, i)
set sc = ##class(Ens.Director).TempStopConfigItem(host, stop, 0)
}
set sc = ##class(Ens.Director).UpdateProduction()
}
Les productions peuvent être arrêtées, ce qui implique d'envoyer une demande à tous les Jobs Business Host pour qu'ils s'arrêtent (en toute sécurité, une fois qu'ils ont terminé leurs messages actifs, le cas échéant).
Conseils:
##class(Ens.Director).StopProduction(timeout=10, force=0)Ens.Director:StopProduction avec un délai plus long.OnStop.Ce qui est important ici, c'est que la production est la somme totale des Business Hosts :
Cela nous amène au cycle de vie des Business Hosts.
Les Business Hosts sont composés de Business Hosts Jobs identiques (en fonction de la valeur du paramètre Pool Size). Le démarrage d'un Business Host implique le démarrage de tous les Business Hosts Jobs. Ils sont démarrés en parallèle.
Business Host Job individuel commence comme ceci :
Une fois le point (4) effectué, la tâche ne peut plus modifier les paramètres ou le code. Ainsi, lorsque vous importez un nouveau code et de nouveaux paramètres par défaut, cela n'affecte pas les tâches d'interopérabilité en cours d'exécution.
L'arrêt du Business Host Job signifie le suivant :
OnMessage pour BO, OnProcessInput pour BS, la méthode d'état S<int> pour les BP BPL, et la méthode On* pour les BP).force=0, la mise à jour de la production échoue pour ce Business Host (et vous verrez un bouton rouge Update dans le SMP).timeout.force=1.La mise à jour du Business Host signifie l'arrêt des tâches en cours d'exécution pour le Business Host et le démarrage de nouvelles tâches.
Tous les Business Hosts commencent immédiatement à utiliser les nouvelles versions des régles Business Rules, Routing Rules et des DTL dès qu'elles sont disponibles. Le redémarrage d'un Business Host n'est pas nécessaire pour cela.
Il arrive cependant que les mises à jour de la production nécessitent l'arrêt de certains Business Hosts.
Considérons la situation. Vous disposez d'une règle de routage Routing Rule X qui achemine les messages vers le processus Business Process A ou B en fonction de critères arbitraires. Dans un nouveau commit, vous ajoutez simultanément:
Dans ce scénario, vous ne pouvez pas charger la règle d'abord et mettre à jour la production ensuite. En effet, la règle nouvellement compilée commencerait immédiatement à router les messages vers le Business Process C, qu'InterSystems IRIS n'a peut-être pas encore compilé, ou que l'interopérabilité n'a pas encore mis à jour pour l'utiliser. Dans ce cas, vous devez désactiver le Business Host avec une règle de routage, mettre à jour le code, mettre à jour la production et réactiver le Business Host.
Remarques:
Les dépendances entre les Business Hosts sont essentielles. Imaginons que vous ayez des processus Business Hosts A et B, dans lesquels A envoie des messages à B. Dans un nouveau commit, vous ajoutez simultanément :
Dans ce scénario, nous DEVONS mettre à jour le Processus B d'abord et le Processus A ensuite. Vous pouvez procéder de deux manières :
Une variante plus difficile de ce thème, où les nouvelles versions des Processus A et B sont incompatibles avec les anciennes versions, nécessite un arrêt des Business Hosts.
Si vous savez qu'après la mise à jour, un Business Host ne pourra plus traiter les anciens messages, vous devez vous assurer que la file d'attente du Business Host est vide avant la mise à jour. Pour ce faire, désactivez tous les Business Hosts qui envoient des messages au Business Host et attendez que sa file d'attente soit vide.
Tout d'abord, une petite introduction sur le fonctionnement des BPL BP. Après avoir compilé un BPL BP, deux classes sont créées dans le paquet, avec le même nom qu'une classe BPL complète :
Thread1 contient les méthodes S1, S2, .... SN, qui correspondent à des activités au sein de BPLContext contient toutes les variables de contexte ainsi que le prochain état que BPL exécutera (c'est-à-dire S5).La classe BPL est également persistante et stocke les demandes en cours de traitement.
BPL fonctionne en exécutant des méthodes S dans une classe Thread et en mettant à jour la table de la classe BPL, la table Context et la table Thread1, où un message "en cours de traitement" est une ligne dans un tableau BPL. Une fois la requête traitée, BPL supprime les entrées BPL, Context et Thread. Puisque les BPL BP sont asynchrones, une tâche BPL peut traiter simultanément de nombreuses requêtes en sauvegardant des informations entre les appels S et en passant d'une requête à l'autre.
Par exemple, BPL traite une requête jusqu'à ce qu'il arrive à une activité sync - en attendant une réponse de BO. Il sauvegarde le contexte actuel sur le disque, avec la propriété %NextState (dans la classe Thread1) fixée à la méthode S de l'activité de réponse, et travaille sur d'autres requêtes jusqu'à ce que BO réponde. Après la réponse de BO, BPL charge le contexte en mémoire et exécute la méthode correspondant à un état sauvegardé dans la propriété %NextState.
Maintenant, que se passe-t-il lorsque nous mettons à jour le BPL ? Tout d'abord, nous devons vérifier qu'au moins une des deux conditions est remplie :
Si au moins une condition est remplie, nous sommes prêts à démarrer. Soit il n'y a pas de demandes de pré-mise à jour à traiter par BPL après la mise à jour, soit les états sont ajoutés à la fin, ce qui signifie que les anciennes demandes peuvent également être traitées (en supposant que les demandes de pré-mise à jour sont compatibles avec les activités et le traitement de BPL après la mise à jour).
Mais que se passe-t-il si vous avez des demandes actives en cours de traitement et que BPL change l'ordre des états ? Idéalement, si vous pouvez attendre, désactivez les appelants BPL et attendez que la file d'attente soit vide. Vérifiez que le tableau Contexte est également vide. N'oubliez pas que la file d'attente n'affiche que les demandes non traitées, et que le tableau Contexte stocke les demandes en cours de traitement, de sorte qu'il peut arriver qu'un BPL très occupé affiche une file d'attente nulle, et c'est normal. Ensuite, désactivez le BPL, effectuez la mise à jour et activez tous les Business Hosts précédemment désactivés.
Si ce n'est pas possible (généralement dans le cas où le BPL est très long, par exemple, je me souviens avoir mis à jour un BPL qui prenait environ une semaine pour traiter une demande, ou si la fenêtre de mise à jour est trop courte), utilisez l'outil BPL versioning.
Vous pouvez également écrire un script de mise à jour. Dans ce script de mise à jour, associez les anciens next states aux nouveaux next states et exécutez-le sur le tableau Thread1 afin que le BPL mis à jour puisse traiter les anciennes requêtes. BPL, bien sûr, doit être désactivé pendant la durée de la mise à jour.
Ceci dit, il s'agit d'une situation extrêmement rare, et généralement, vous n'avez pas besoin de faire cela, mais si jamais vous devez le faire, voici comment procéder.
L'interopérabilité met en œuvre un algorithme sophistiqué pour minimiser le nombre d'actions nécessaires pour actualiser la production après la modification du code sous-jacent. Appelez UpdateProduction avec un délai d'attente sûr à chaque mise à jour de SDS. Pour chaque mise à jour de code, vous devez décider d'une stratégie de mise à jour.
La réduction de la quantité de code compilé à l'aide de git diffs permet de réduire le temps de compilation, mais la "mise à jour" du code en lui-même et sa recompilation ou la "mise à jour" des paramètres avec les mêmes valeurs ne déclenchent pas ou ne requièrent pas de mise à jour de la production.
La mise à jour et la compilation des règles de gestion "Business Rule", des règles de routage "Routing Rules" et des DTL les rendent immédiatement accessibles sans mise à jour de la production.
Enfin, la mise à jour de la production est une opération sûre qui ne nécessite généralement pas de temps d'arrêt.
L'auteur tient à remercier @James MacKeith, @Dmitry Zasypkin et @Regilo Regilio Guedes de Souza pour leur aide précieuse dans la rédaction de cet article.
Je reçois généralement des plaintes de nos clients concernant l'actualisation automatique des pages Web BPL et DTL. C'est un problème courant parmi les utilisateurs débutants, mais pour les développeurs expérimentés aussi, ils oublient d'enregistrer les modifications régulièrement et automatiquement la page Web est rechargée, perdant tout le travail effectué.
Cet article décrit et contient un exemple de la manière d'intégrer un fichier PDF externe dans un segment HL7, plus précisément dans ADT_A01:2.3.1 OBX(). Cela peut être utile lorsqu'on tente de mettre des images ou d'autres données externes dans un message HL7. Dans cet exemple, le nom du fichier PDF à intégrer est fourni dans le message HL7 entrant dans le champ OBX(1):ObservationValue.
Les stipulations de base de cet exemple sont les suivantes :

En utilisant EnsLib.File.InboundAdapter, l'exemple a deux Services Métiers configurés. L'un est destiné à recevoir des fichiers PDF à l'aide de l'EnsLib.File.PassthroughService intégré. L'autre accepte les messages HL7 en utilisant le service intégré EnsLib.HL7.Service.FileService.
PDF Processing
L'ordre de ces composants est essentiel car le fichier PDF doit être retiré en premier. Il est également important que l'Archive Path et le Work Path du PDF Business Service soient définis sur le même chemin de répertoire. Cela permet d'enregistrer localement une copie du PDF qui sera utilisée ultérieurement pour intégrer les données dans le message HL7.
Pour que le Business Service enregistre le fichier PDF dans ce répertoire Archive/Work Path, il faut appeler SendRequestAsyn(). Cette méthode est appelée par défaut lors d'un envoi entre les composants d'Ensemble/HealthShare.
Pour ce faire, le PDF Business Service est configuré pour envoyer le message PDF à une Business Operation personnalisée qui accepte le message sans effectuer d'autres actions.
Remarque : Le composant cible du PDF Business Service n'est pas pertinent pour cet exemple, mais il pourrait être construit pour effectuer toute action supplémentaire avec le message PDF.
HL7 Processing
Le message HL7 du service commercial est envoyé à un processus commercial personnalisé. Ce processus appelle un BPL qui identifie et ouvre le fichier PDF approprié, puis appelle un DTL qui se charge de l'intégration des données dans le message HL7.
=== BPL ===
Le BPL accomplit les tâches suivantes :
</ol>
=== DTL ===
</ol>
=== DTL Code Action ===
//Récupérer l'objet du flux PDF précédemment enregistré
Set pdfStreamContainer = ##Class(Ens.StreamContainer).%OpenId(context.StreamContainerID)
Try {
Set pdfStreamObj = pdfStreamContainer.StreamGet()
}
Catch {
$$$TRACE("Error opening stream object ID = "_context.StreamContainerID)
Quit
}
//Set PDF stream object into new OBX:5 segment
Set status = target.StoreFieldStreamBase64(pdfStreamObj,"OBX("_count_"):ObservationValue(1)")
Set ^testglobal("status",$H) = status
Sample Production
Voici la liste des fichiers inclus dans le modèle ci-joint.
</ol>
Cet exemple a été construit sur Ensemble 2016.2.0 mais il a été testé sur Ensemble 2015.1.2 sans aucun problème de compatibilité. Le fichier .zip se trouve ici :
Je suis confronté à un problème où je dois récupérer un numéro d'identification dans un tableau SQL externe lorsqu'il n'existe pas dans un message HL7, puis l'ajouter au message HL7.
J'ai construit la logique dans un BPL qui vérifie l'absence d'ID, puis extrait l'ID du tableau SQL (et sauvegarde sa valeur en utilisant la fonctionnalité de contexte dans le BPL), mais je ne sais pas comment prendre l'ID et l'ajouter au message HL7 avant de le transmettre à un routeur.