#Service aux entreprises

0 Abonnés · 7 Publications

Un service métier est une partie de la production d'interopérabilité d'InterSystems Ensemble qui est responsable de l'acceptation des demandes provenant d'applications externes.

Article Lorenzo Scalese · Jan 22, 2025 5m read

Mise en œuvre de l'idée DPI-I-456

Idée

Le rôle de cet échantillon

Cet exemple a été cloné à partir de la version iris-interoperability-template. J'ai reconfiguré la production d' interopérabilité Production avec un adaptateur Inbound HTTP Adapter qui est utilisé par un service métier HTTP Business Service. Les détails de la configuration du service métier sont spécifiés dans la rubrique des paramètres par défaut du système System Default Settings. J'ai configuré le paramètre de l'intervalle d'appel pour appeler le serveur HTTPS une fois par heure. Vous pouvez modifier l'URL et la fréquence dans les paramètres du service. Screenshot

À l'origine, le service HTTP avait deux cibles. Le corps de réponse de chaque appel était envoyé en tant que message générique HTTP à un processus métier BPL et à une opération de fichier qui sauvegardait les données dans un dossier iris-http-calls.

Le service HTTP envoie un message générique HTTP à une opération de fichier. Ensuite, un service de fichiers envoie le fichier à un processus métier BPL.

Conditions préalables

Assurez-vous d'avoir installé git et Docker desktop.

Installation: ZPM

Ouverture de l'espace de noms IRIS avec l'interopérabilité activée. Ouvrez le terminal et appelez: USER>zpm "install iris-http-calls"

Installation: Docker

Clone/git extrait le référentiel dans n'importe quel répertoire local.

git clone https://github.com/oliverwilms/iris-http-calls.git

Ouvrez le terminal dans ce répertoire et lancez:

docker-compose build
  1. Lancez le conteneur IRIS avec votre projet:
docker-compose up -d

Comment exécuter l'échantillon

Ouvrez la production et lancez-la si elle n'est pas déjà en cours d'exécution. Il effectue des appels HTTP vers le serveur HTTPS à l'aide d'une URL.

Comment modifier le modèle

Ce référentiel est prêt à être codé dans VSCode avec le plugin ObjectScript. Installez VSCode, Docker et le pluginObjectScript et ouvrez le dossier dans VSCode.

Utilisez le menu pratique VSCode pour accéder à l'éditeur de règles de production et de règles métier et lancez un terminal: Screenshot 2020-10-29 at 20 15 56

utilisation des variables d'environnement

Cet exemple montre la façon dont vous pouvez introduire des variables env dans votre environnement dev. Supposons que vous ayez besoin de configurer la production avec un jeton secret pour accéder à une API à accès limité. Bien sûr, vous ne voulez pas exposer le secret à GitHub. Dans ce cas, le mécanisme des variables Env peut être utile. Tout d'abord, introduisez le fichier .env et configurez .gitignore pour filtrer .env à partir de git.

Ajoutez ensuite le jeton secret dans .env sous la forme ENV_VARIABLE="TOKEN VALUE"

L'introduction suivante consiste à faire importer les variables d'environnement dans dockerfile. Pour que cela fonctionne, ajoutez la section environnement dans [docker-compose.yml] (https://github.com/intersystems-community/iris-interoperability-template/blob/d2d7114de7c551e308e742359babebff5d535821/docker-compose.yml), par exemple:

environnement:
      - SAMPLE_TOKEN=${SAMPLE_TOKEN}

Ensuite, vous pourrez initialiser le conteneur en cours d'exécution avec les données des variables env, par exemple avec l'appel suivant, qui utilise la valeur du fichier .env comme paramètre de la production:

USER> d ##class(dc.Demo.Setup).Init($system.Util.GetEnviron("SAMPLE_TOKEN"))

paramètres de production du gestionnaire de paquets

Les utilisateurs de ce module peuvent utiliser des paramètres pour transmettre des données au module lors de l'installation et personnaliser le chemin d'accès au fichier pour l'opération de fichier et le service de fichier, ainsi que modifier l'URL. Il peut être utile lorsque les paramètres de configuration sont des jetons secrets permettant d'accéder à une API particulière. En tant que spécialiste, vous pouvez fournir de tels paramètres avec une balise par défaut dans module.xml.

<Default Name="FilePath" Value="iris_http_calls" />
<Default Name="UrlModify" Value="/Patient?_id=egqBHVfQlt4Bw3XGXoxVxHg3" />

Ces paramètres par défaut permettent aux utilisateurs d'appeler l'installation du paquet avec la possibilité de transmettre des paramètres. Par exemple, l'appel à l'installation peut être exécuté sous la forme suivante:

zpm "install iris-http-calls -D FilePath=iris_http_calls -D UrlModify=/MedicationStatement?patient=egqBHVfQlt4Bw3XGXoxVxHg3"
USER>zpm "install iris-http-calls -D FilePath=iris_http_calls -D UrlModify=/MedicationStatement?patient=egqBHVfQlt4Bw3XGXoxVxHg3"

[USER|iris-http-calls]        Reload START (/usr/irissys/mgr/.modules/USER/iris-http-calls/0.3.37/)
[USER|iris-http-calls]        Reload SUCCESS
[iris-http-calls]       Module object refreshed.
[USER|iris-http-calls]        Validate START
[USER|iris-http-calls]        Validate SUCCESS
[USER|iris-http-calls]        Compile START
[USER|iris-http-calls]        Compile SUCCESS
[USER|iris-http-calls]        Activate START
[USER|iris-http-calls]        Configure START
[USER|iris-http-calls]        Configure SUCCESS
[USER|iris-http-calls]        Activate SUCCESS

Les paramètres par défaut sont utilisés pour configurer la production dans l'appel suivant:

<Invoke Class="dc.Demo.Setup" Method="Init" >
  <Arg>${FilePath}</Arg>
  <Arg>${UrlModify}</Arg>
</Invoke>

La méthode Init de la classe dc.Demo.Setup configure le service et l'opération de fichier à l'aide du paramètre FilePath. Le paramètre UrlModify est utilisé pour modifier l'URL du service HTTP.

La production appelle le serveur HTTPS à l'aide de l'URL modifiée selon CallInterval. Le corps de réponse est envoyé dans un StreamContainer à une FileOperation. Un service de fichiers lit le fichier et transmet un conteneur de flux à un processus BPL.

0
0 34
Article Lorenzo Scalese · Oct 30, 2024 10m read

L'utilisation traditionnelle d'une production IRIS consiste, pour un adaptateur entrant, à recevoir des données d'une source externe, à envoyer ces données à un service IRIS, puis à faire en sorte que ce service envoie ces données par l'intermédiaire de la production.

Cependant, grâce à un adaptateur entrant personnalisé, nous pouvons faire en sorte qu'une production IRIS soit plus performante. Nous pouvons utiliser une production IRIS pour traiter les données de notre propre base de données sans aucun déclencheur externe.

BEn utilisant une production IRIS de cette manière, vos tâches de traitement des données peuvent désormais tirer parti de toutes les fonctionnalités intégrées d'une production IRIS, y compris:

  • Suivi et contrôle avancés
  • Traitement multithread pour l'évolutivité
  • Logique métier basée sur la configuration
  • Opérations IRIS intégrées pour se connecter rapidement à des systèmes externes
  • Récupération rapide des défaillances du système

La documentation pour créer un adaptateur entrant personnalisé peut être consultée à: https://docs.intersystems.com/hs20231/csp/docbook/DocBook.UI.Page.cls?KEY=EGDV_adv#EGDV_adv_adapterdev_inbound

Regardons 3 exemples d'une production simple configurée pour traiter des objets "Fish" à partir d'une base de données.

Dans le premier exemple, nous allons créer une production pilotée par les données qui traitera continuellement les données.

Dans le deuxième exemple, nous modifierons cette production pour traiter les données uniquement à des moments précis.

Dans le troisième exemple, nous modifierons cette production pour traiter les données uniquement lorsqu'elles sont déclenchées via une tâche système.

Exemple 1: Traitement continu des données

Cet exemple est une simple production configurée pour traiter continuellement des objets "Fish" à partir d'une base de données. Tout ce que fait la production est de rechercher continuellement de nouveaux objets fish, de convertir ces objets fish en JSON, puis de recracher ce JSON dans un fichier.

Tout d'abord, nous créons l'objet Fish que nous avons l'intention de traiter:

Class Sample.Fish Extends (%Persistent, Ens.Util.MessageBodyMethods, %JSON.Adaptor, %XML.Adaptor)
{

Parameter ENSPURGE As%Boolean = 0;Property Type As%String;Property Size As%Numeric;Property FirstName As%String;Property Status As%String [ InitialExpression = "Initialized" ];
Index StatusIndex On Status;
}

L'état est important car c'est ainsi que nous distinguerons l'état des objets fish non traités de l'état des objets traités.

En fixant ENSPURGE à 0 empêchera cet objet d'être purgé avec les en-têtes du message à l'avenir.

Deuxièmement, nous créons un adaptateur personnalisé pour rechercher les nouveaux objets fish:

Class Sample.Adapter.FishMonitorAdapter Extends Ens.InboundAdapter
{

/// La valeur d'état d'objet Fish sera demandée par l'adaptateur. Tous les objets Fish correspondants auront leur état défini par SetFishStatus et seront ensuite envoyés au service.Property GetFishStatus As%String [ InitialExpression = "Initialized", Required ];/// L'état d'objet Fish correspond à la valeur que le service attribue à l'objet Fish avant qu'il ne soit envoyé au service.Property SetFishStatus As%String [ InitialExpression = "Processed", Required ];Parameter SETTINGS = "GetFishStatus:Basic,SetFishStatus:Basic";Parameter SERVICEINPUTCLASS = "Sample.Fish";
Method OnTask() As%Status
{
	//Curseur pour rechercher les objets Fish correspondantsset getFishStatus = ..GetFishStatus
	&sql(declare fishCursor cursorforselectIDinto :fishId
		from Sample.Fish
		whereStatus = :getFishStatus)
	
	//Exécution du curseur
	&sql(open fishCursor)
	for {
		&sql(fetch fishCursor)
		quit:SQLCODE'=0//Changez l'état de chaque objet Fish correspondant et envoyez-le au service (BusinessHost).set fishObj = ##class(Sample.Fish).%OpenId(fishId)
		set fishObj.Status = ..SetFishStatus$$$ThrowOnError(fishObj.%Save())
		$$$ThrowOnError(..BusinessHost.ProcessInput(fishObj))
	}
	&sql(close fishCursor)
	if SQLCODE < 0 {
		throw##class(%Exception.SQL).CreateFromSQLCODE(SQLCODE,%msg)
	}
	
	quit$$$OK
}

La méthode OnTask() recherche tous les objet Fish correspondant à la valeur GetFishStatus configurée. Pour chaque objet Fish trouvé, elle modifie son état en fonction de la valeur SetFishStatus configurée, puis le transmet à la méthode ProcessInput du service.

Troisièmement, nous créons un service personnalisé pour utiliser cet adaptateur:

Class Sample.Service.FishMonitorService Extends Ens.BusinessService
{

/// Élément de configuration auquel les messages doivent être envoyésProperty TargetConfigName As Ens.DataType.ConfigName;Parameter SETTINGS = "TargetConfigName:Basic";Parameter ADAPTER = "Sample.Adapter.FishMonitorAdapter";
Method OnProcessInput(pInput As Sample.Fish, pOutput As%RegisteredObject) As%Status
{
    quit:..TargetConfigName=""//Envoyer l'objet Fish vers la cible configuréequit..SendRequestAsync(..TargetConfigName, pInput)
}

}

Ce service prend les objet Fish en entrée et les transmet via une requête asynchrone à la cible configurée.

Quatrièmement, nous créons un processus métier personnalisé pour convertir l'objet Fish en JSON.

Class Sample.Process.FishToJSONProcess Extends Ens.BusinessProcess
{

/// Élément de configuration auquel les messages doivent être envoyésProperty TargetConfigName As Ens.DataType.ConfigName;Parameter SETTINGS = "TargetConfigName:Basic";
Method OnRequest(pRequest As Sample.Fish, Output pResponse As Ens.Response) As%Status
{
	//Convertissez l'objet Fish en un flux JSONdo pRequest.%JSONExportToStream(.jsonFishStream)
	//Créez un nouveau conteneur de flux avec un flux JSONset tRequest = ##class(Ens.StreamContainer).%New(jsonFishStream)
	//Envoyez le conteneur de flux à la cible configuréequit..SendRequestAsync(..TargetConfigName, tRequest, 0)
}

Method OnResponse(request As Ens.Request, ByRef response As Ens.Response, callrequest As Ens.Request, callresponse As Ens.Response, pCompletionKey As%String) As%Status
{
    quit$$$OK
}

}

La méthode OnRequest() est la seule méthode qui agisse. Il accepte l'objet Fish, génère un flux JSON à partir de l'objet Fish, conditionne ce flux dans un conteneur Ens.StreamContainer, puis transmet ce conteneur de flux via une requête asynchrone à la cible configurée.

Enfin, nous configurons la production:

Class Sample.DataProduction Extends Ens.Production
{

XData ProductionDefinition
{
<Production Name="Sample.DataProduction" LogGeneralTraceEvents="false">
  <Description></Description>
  <ActorPoolSize>2</ActorPoolSize>
  <Item Name="Sample.Service.FishMonitorService" Category="" ClassName="Sample.Service.FishMonitorService" PoolSize="1" Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule="">
    <Setting Target="Host" Name="TargetConfigName">Sample.Process.FishToJSONProcess</Setting>
  </Item>
  <Item Name="Sample.Process.FishToJSONProcess" Category="" ClassName="Sample.Process.FishToJSONProcess" PoolSize="1" Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule="">
    <Setting Target="Host" Name="TargetConfigName">EnsLib.File.PassthroughOperation</Setting>
  </Item>
  <Item Name="EnsLib.File.PassthroughOperation" Category="" ClassName="EnsLib.File.PassthroughOperation" PoolSize="1" Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule="">
    <Setting Target="Adapter" Name="FilePath">C:\temp\fish\</Setting>
  </Item>
</Production>
}

}

Il ne reste plus qu'à la tester. Pour cela, il suffit d'ouvrir une fenêtre de terminal et de créer un nouvel objet Fish.

En regardant les messages de production, nous pouvons voir que l'objet Fish a été trouvé et transformé:

Nous pouvons inspecter la trace des deux messages:

En regardant le dossier de sortie (C:\temp\fish\), nous pouvons voir le fichier de sortie:

Exemple 2: Traitement des données basé sur les horaires

Pour les cas d'utilisation où nous ne voulons traiter les données qu'à des moments précis, comme la nuit, nous pouvons configurer le service pour qu'il s'exécute selon des horaires précis.

Pour modifier l'exemple 1 pour qu'il fonctionne selon des horaires, nous créons d'abord une spécification de l'horaire. La documentation sur la manière de procéder est disponible ici: https://docs.intersystems.com/iris20231/csp/docbook/DocBook.UI.PortalHelpPage.cls?KEY=Ensemble%2C%20Schedule%20Editor

Ensuite, nous modifions la configuration du service pour utiliser cet horaire:

Class Sample.DataProduction Extends Ens.Production
{

XData ProductionDefinition
{
<Production Name="Sample.DataProduction" LogGeneralTraceEvents="false">
  <Description></Description>
  <ActorPoolSize>2</ActorPoolSize>
  <Item Name="Sample.Service.FishMonitorService" Category="" ClassName="Sample.Service.FishMonitorService" PoolSize="1" Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule="@Midnight Processing">
    <Setting Target="Host" Name="TargetConfigName">Sample.Process.FishToJSONProcess</Setting>
  </Item>
  <Item Name="Sample.Process.FishToJSONProcess" Category="" ClassName="Sample.Process.FishToJSONProcess" PoolSize="1" Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule="">
    <Setting Target="Host" Name="TargetConfigName">EnsLib.File.PassthroughOperation</Setting>
  </Item>
  <Item Name="EnsLib.File.PassthroughOperation" Category="" ClassName="EnsLib.File.PassthroughOperation" PoolSize="1" Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule="">
    <Setting Target="Adapter" Name="FilePath">C:\temp\fish\</Setting>
  </Item>
</Production>
}

}

Maintenant, lorsque nous regardons cet onglet "Tâches" du service, nous voyons qu'il n'y a aucun tâche en cours:

Désormais, ce service n'aura plus que des tâches à exécuter entre minuit et 1 heure du matin.

Exemple 3: Traitement de données sur la base des événements avec le Gestionnaire de tâches

Pour les cas d'utilisation où nous ne voulons traiter les données qu'une seule fois à un moment précis ou lorsqu'un événement particulier a lieu, nous pouvons configurer le service pour qu'il ne s'exécute que lors de l'exécution d'une tâche système.

Pour modifier l'exemple 1 afin qu'il ne s'exécute que lorsqu'il est déclenché par une tâche, nous créons d'abord une tâche personnalisée pour déclencher le service.

Class Sample.Task.TriggerServiceTask Extends%SYS.Task.Definition
{

/// Le nom du service métier que cette tâche doit exécuter.Property BuinessServiceName As%String [ Required ];
Method OnTask() As%Status
{
	#dim pBusinessService As Ens.BusinessService
	$$$ThrowOnError(##class(Ens.Director).CreateBusinessService(..BuinessServiceName, .pBusinessService))
	Quit pBusinessService.OnTask()
}

}

Deuxièmement, nous configurons une nouvelle tâche système. La documentation sur la configuration des tâches système est disponible ici: https://docs.intersystems.com/iris20233/csp/docbook/Doc.View.cls?KEY=GSA_manage_taskmgr

Ceci est la partie personnalisée du processus de configuration pour cet exemple:

En outre, je configure la tâche pour qu'elle soit exécutée à la demande, mais vous pouvez aussi établir un horaire.

Enfin, nous configurons la production:

Class Sample.DataProduction Extends Ens.Production
{

XData ProductionDefinition
{
<Production Name="Sample.DataProduction" LogGeneralTraceEvents="false">
  <Description></Description>
  <ActorPoolSize>2</ActorPoolSize>
  <Item Name="Sample.Service.FishMonitorService" Category="" ClassName="Sample.Service.FishMonitorService" PoolSize="0" Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule="">
    <Setting Target="Host" Name="TargetConfigName">Sample.Process.FishToJSONProcess</Setting>
  </Item>
  <Item Name="Sample.Process.FishToJSONProcess" Category="" ClassName="Sample.Process.FishToJSONProcess" PoolSize="1" Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule="">
    <Setting Target="Host" Name="TargetConfigName">EnsLib.File.PassthroughOperation</Setting>
  </Item>
  <Item Name="EnsLib.File.PassthroughOperation" Category="" ClassName="EnsLib.File.PassthroughOperation" PoolSize="1" Enabled="true" Foreground="false" Comment="" LogTraceEvents="false" Schedule="">
    <Setting Target="Adapter" Name="FilePath">C:\temp\fish\</Setting>
  </Item>
</Production>
}

}

Notez que nous avons fixé le PoolSize de Sample.Service.FishMonitorService à 0.

Il ne reste plus qu'à la tester. Pour cela, il suffit d'ouvrir une fenêtre de terminal et de créer un nouvel objet Fish.

En regardant les messages de production, nous pouvons voir que l'objet Fish n'a pas encore été transformé:

Ensuite, nous exécutons la tâche à la demande pour déclencher le service:

Maintenant, en regardant les messages de production, nous pouvons voir que le service a été déclenché, ce qui a permis de trouver et de traiter l'objet Fish:

Nous pouvons inspecter la trace des deux messages:

En regardant le dossier de sortie (C:\temp\fish\), nous pouvons voir le fichier de sortie:

Conclusion

Les exemples ci-dessus sont assez simples. Vous pouvez cependant configurer les productions pour en faire beaucoup plus. Y compris…

En fait, il est possible de réaliser ici tout ce qui peut être fait dans le cadre d'une production typique d'IRIS.

0
0 44
Article Lorenzo Scalese · Août 8, 2024 3m read

Parfois, nous devons convertir le message FHIR en HL7 V2, par exemple pour enregistrer un patient dans le système PACS.
Dans cet article, les étapes à suivre pour obtenir les résultats souhaités en utilisant la production du serveur IRIS FHIR seront expliquées.

Voici les étapes à suivre:

  1. Assurez-vous que la production du serveur FHIR est démarrée.
  2. Enregistrez le service métier avec le point de terminaison FHIRServer.
  3. Définissez les processus métier pour convertir les messages FHIR en SDA, puis convertissez SDA en HL7 v2.
  4. Publiez la ressource JSON sur le point de terminaison FHIRServer et obtenez la réponse HL7 V2.

Examinons les étapes en détail.
 

Étape 1. Assurez-vous que la production du serveur FHIR est démarrée

Ouvrez la page de production et assurez-vous que la Production est démarrée. À l'étape suivante, nous devons nous assurer que le service commercial HS.FHIRServer.Interop.Service est enregistré auprès de FHIRServer


Step 2. Étape 2. Enregistrez le service métier avec le point de terminaison FHIRServer.

Depuis le portail de gestion, cliquez sur l'onglet Health (Santé)

Cliquez ensuite sur Configuration FHIR dans la liste, puis cliquez sur Server Configuration (configuration du serveur)

Sélectionnez le point de terminaison et assurez-vous que HS.FHIRServer.Interop.Service (service commercial défini dans la production) est défini sous le nom Service Config Name.

Étape 3. Définissez les processus métier pour convertir les messages FHIR en SDA, puis convertissez SDA en HL7 v2.

Définissez le rpocessus métier (le processus Solution.BP.Process est déjà défini dans l'application).
Veuillez noter que nous appliquons ici une condition selon laquelle le point de terminaison doit contenir une augmentation hl7 pour procéder à la conversion, sinon il est considéré comme une demande FHIR normale.


Transmettez ensuite le message au processus FHIR_SDA qui le convertira en SDA.
FHIR_SDA est dérivé d'une classe Solution.BP.Process définie par l'utilisateur.
Après conversion FHIR_SDA, le processus transmet le message au processus SDA_HL7
Le processus SDA_HL7 est dérivé d'une classe Solution.BP.SDATransformProcess définied  par l'utilisateur qui convertit le message SDA en message HL7 V2.


Définissez les processus de production comme suit:


Étape 4. Publiez la ressource JSON sur le point de terminaison FHIRServer et obtenez la réponse HL7 V2.

Depuis Postman, appelez le point de terminaison FHIRServer à l'aide de la méthode Post.
Notre point de terminaison FHIRServer est ci-dessous:
http://localhost:32783/csp/fhirserver/fhir/r4/hl7

REMARQUE:Notre point de terminaison FHIRServer est http://localhost:32783/csp/fhirserver/fhir/r4/, mais nous passons hl7 comme argument pour détecter à partir du processus métier de production qu'il ne s'agit pas d'une demande Post FHIR normale mais d'une demande de transformation du message FHIR.

Il s'agit de la même fonctionnalité que celle que nous pouvons utiliser à partir de nos applications Web. 
Sélectionnez la ressource patient, puis cliquez sur la ressource dans la liste, sélectionnez l'onglet HL7 FHIR ou Détails de la ressource, et cliquez sur le bouton "Transformer FHIR en HL7 V2"

L'application obtiendra le message de transformation HL7 V2 à l'aide de la production du serveur FHIR.



Transformation de HL7 V2 à FHIR

Sélectionnez "HL7 to FHIR" dans le menu et entrez les données HL7 V2. Cliquez sur le bouton de conversion pour transformer le message HL7 en message FHIR

La transformation de HL7 en FHIR utilise également la production pour convertir le message HL7 V2 en message FHIR.

Le service métier HL7_Http_Service envoie le message HL7 au processus HL7_SDA, puis HL7_SDA envoie les données SDA au processus SDA_FHIR, qui les convertit finalement en FHIR

Pour plus de détails et une révision du code, veuillez visiter la page d'application de l'échange ouvert iris-fhir-lab .
Merci!

0
0 69
Article Guillaume Rongier · Juil 12, 2023 4m read

L' adaptateur Telegram pour InterSystems IRIS sert de pont entre la populaire plateforme de messagerie Telegram et InterSystems IRIS, facilitant une communication et un échange de données transparents. En exploitant les capacités de l'API Telegram, l'adaptateur permet aux développeurs de créer des chatbots robustes, d'automatiser des tâches et d'intégrer Telegram aux applications d'InterSystems IRIS.

Les scénarios les plus courants dans lesquels l'adaptateur Telegram peut être utilisé sont les suivants :

0
0 114
Article Guillaume Rongier · Jan 4, 2023 11m read

Les systèmes EHR (Electronic Health Record) sont modélisés dans un format/structure propriétaire et ne sont pas basés sur des modèles du marché tels que FHIR ou HL7. Certains de ces systèmes peuvent interopérer des données dans un format propriétaire pour FHIR et d'autres modèles de marché, mais pas tous. InterSystems dispose de deux plateformes capables d'interopérer des formats propriétaires pour ceux du marché : InterSystems HealthShare Connect et InterSystems IRIS for Health. La fonctionnalité de transformation (DTL - Data Transformation Language) de ces plateformes peut recevoir des données dans n'importe quel format, structure ou canal de communication (CSV, JSON, XML, et autres via FTP, File, HTTP, etc.) et les transformer directement en formats du marché (FHIR, CDA, HL7, etc.). Cependant, InterSystems dispose d'un format intermédiaire appelé SDA (Summary Document Architecture) qui est utilisé par ces plateformes pour générer sans effort des FHIR STU, R3, R4, HL7v2, HL7v3, etc. En outre, lorsqu'elles sont au format SDA, les données de santé peuvent être conservées dans le RCU HealthShare. Ainsi, le format propriétaire/personnel est d'abord transformé en SDA, puis les données peuvent être automatiquement converties dans n'importe quel format du marché, ainsi que sauvegardées dans HealthShare. Dans cet article, nous allons vous montrer comment transformer des données propriétaires/personnalisées en SDA à l'aide d'IRIS for Health. L'exemple de données que nous avons utilisé a été généré par le projet de génération de données en masse SYNTHEA (https://synthea.mitre.org/downloads). Nous allons convertir 1000 patients d'un fichier CSV en SDA, en utilisant les fonctions d'interopérabilité d'IRIS for Health.

Application de soutien aux articles – custom2sda

Installation de l'application d'exemple qui sera utilisée avec cet article en suivant les instructions :

Si vous voulez installer en utilisant ZPM :

1. Ouvrez le Namespace IRIS avec l'interopérabilité activée.
2. Ouvrez le Terminal et appelez : USER>zpm "install custom2sda"

Si vous voulez installer en utilisant Docker :

1. Clonez Git et tirez le repo dans n'importe quel répertoire local :

$ git clone https://github.com/yurimarx/custom2sda.git

2. Ouvrez le terminal dans ce répertoire et exécutez :

$ docker-compose build

3. Lancez le conteneur IRIS avec votre projet :

$ docker-compose up -d

4. Ouvrez la production (http://localhost:52775/csp/healthshare/user/EnsPortal.ProductionConfig.zen?PRODUCTION=customsda.CustomToSDAProduction) et la lancez. (utilizateur _SYSTEM et le mot de passe SYS). Elle lira le fichier patients.csv et le convertira en SDA.

Créer une carte d'enregistrement CSV pour obtenir les données personnalisées/propriétaires

Dans l'étape précédente, vous avez exécuté la production qui a lu le fichier patients.csv et l'a transformé en SDA. Maintenant nous allons faire la même chose avec patients2.csv. Nous pourrions profiter de la production actuelle, mais je voudrais montrer comment créer tout à partir de zéro. Donc, arrêtez cette production, et faisons ce qui suit.

1.    Allez au portail de gestion (http://localhost:52775/csp/sys/%25CSP.Portal.Home.zen?$NAMESPACE=USER, assurez-vous que vous êtes dans l'espace de noms de l'utilisateur).
2.    Créer un CSV Mapper pour le fichier patients2.csv. Interopérabilité > Build > CSV Record Wizard (Assistant d'enregistrement CSV) :

Remarque : sélectionnez CRLF pour Record Terminator (terminateur d'enregistrement)

3.    Cliquez sur "Create RecordMap" pour ouvrir l'interface utilisateur de Record Mapper et modifiez le nom de la classe cible en customsda.Patients2RecordMap.Record :

4.    Sélectionnez BIRTHPLACE et définissez MAXLEN=200 dans le champ Paramètres du type de données. Par défaut, tous les champs %String contiennent 50 caractères, mais BIRTHPLACE et ADDRESS ont besoin de plus d'espace. Faites de même pour le champ ADDRESS :

5.    Cliquez sur le bouton "Save" (Enregistrer) et sur le bouton "Generate" (Générer). Acceptez les options par défaut et cliquez sur Ok pour générer les classes RecordMap.

6.    Cliquez sur "Interoperability" (Interopérabilité) pour passer aux tâches suivantes:

Créer la transformation de données de Custom à SDA

Il est temps d'utiliser le DTL pour construire visuellement la carte de transformation de Custom à SDA.

1.    Cliquez sur Interoperability" > Build > Data Transformations (transformation de données) > Go :

2.    Vous pouvez voir le Data Transformation Builder ici. Cliquez sur le bouton "New" (Nouveau) :

3.    Dans Data Transformation Wizard (Assistant de transformation des données), changez le Package en customsda, et le Name en PatientDTL2 :

4.    À ce stade, nous allons définir la classe de la source. Cliquez sur l'icône de la loupe près du champ "Source Class" :

5.    Cliquez sur Message Classes > customsda > Patients2RecordMap > Record :

6.    À ce stade, la classe "Source Class" devrait ressembler à ceci :

7.    Dans la section Target Type, sélectionnez XML et acceptez Target Class avec la valeur EnsLib.EDI.XML.Document :

8.    Sélectionnez l'icône de la loupe près du Type de document cible et cliquez sur Document XML > SDA3_schema > Container :

Remarque 1 : Le conteneur est l'élément racine de tous les éléments SDA, comme Patient.

Remarque 2 : pour que SDA3_schema soit disponible, les actions suivantes sont nécessaires :
Copier SDA3_schema.xsd dans votre système de fichiers local :

Importez le schéma XSD de SDA3 :

9.    Maintenant, lorsque la source et la cible sont configurées, cliquez sur le bouton OK :

10.    Les champs source et cible sont maintenant disponibles pour le mappage visuel :

11.    Pour créer une transformation, vous devez faire glisser le cercle du champ source et le déposer dans la flèche du champ cible, ligne par ligne.

12.    Dans la section Actions, vous pouvez voir les résultats obtenus :

13.    Après avoir mappé tous les champs, votre liste d'actions ressemblera à ceci :

Remarque : pour les propriétés avec (), vous devez définir l'index car ces propriétés peuvent avoir plus d'un élément. Dans cet exemple, nous n'avons qu'une seule adresse, donc target.{Patient.Addresses(1)….} est configuré avec 1.

14.    Cliquez sur le bouton "Save" (enregistrer) et sur le bouton "Compile" (compiler).

15.    Enfin, cliquez sur le raccourci "Interoperability" pour accéder au menu d'Interoperability :

Créer la production de l'interopérabilité (Interoperability Production), le dernier artefact pour compléter notre travail !

Les productions sont les mécanismes utilisés pour automatiser efficacement les flux d'intégration. Il est temps de créer notre production pour transformer les données des patients du fichier patients2.csv en SDA.

1.    Cliquez sur Interoperability > List > Productions :

2.    Cliquez sur le bouton "New" :

3.    Définissez Customsda sur Package, Patients2Production sur Production Name et Production Type sur Generic. Cliquez sur Ok :

4.    Nous avons maintenant la configuration de production :

5.    Cliquez sur le bouton "Plus" près de "Services" :

Remarque : Les services sont les composants utilisés par les productions pour obtenir des données sources.

6.    Configurez la classe "Service Class" avec la valeur EnsLib.RecordMap.Service.FileService, et le nom du service "Service Name" comme PatientCSVService, et cochez "Enable Now" :

7.    Sélectionnez PatientCSVService et configurez l'onglet Paramètres avec les valeurs

  et cliquez sur "Apply" (appliquer):
●    Chemin du fichier : /opt/user/data/
●    Spécification du fichier : patients2.csv
●    Carte d'enregistrement : Patients2RecordMap
●    Noms des configurations cibles : PatientProcess

8.    Cliquez sur le bouton "Plus" situé près des Opérations :

Remarque : Les opérations sont des composants de production utilisés pour écrire/persister des données sur une cible (bases de données, systèmes, API, services Web, FTP, fichier, etc.)

9.    Configurez l'Opération avec les valeurs suivantes :
●    Classe d'Opération : EnsLib.EDI.XML.Operation.FileOperation
●    Nom d'Opération : PatientSDAOperation
●    Cochez Enable Now

10.    Sélectionnez PatientSDAOperation et définissez la valeur /opt/user/data/ comme chemin de fichier, puis cliquez sur le bouton "Apply" :

11.    Cliquez sur le bouton "Plus" à côté de "Processes" (Processus) :

Remarque : les processus sont le composant de production permettant de coordonner le flux de données.

12.    Configurez le processus métier avec les valeurs suivantes :
●    Classe du processus métier: EnsLib.MsgRouter.RoutingEngine
●    Nom de règle de routage : customsda.PatientRouterRule2
●    Nom du processus métier: PatientProcess
●    Cochez Enable Now

13.    Jusqu'à présent, nous avons créé tous les composants :

14.    Sélectionnez PatientProcess et allez à l'onglet "Settings" > icône de loupe près de "Business Rule Name" (Nom de règle de routage) :

15.    Maintenant, nous allons configurer la règle de routage "Routing Rule" dans l'éditeur de règles "Rule Editor" :

16.    Faites un double-clic sur le composant de contrainte et configurez la Source avec PatientCSVService et la Classe de message avec customsda.Patients2RecordMap.Record :

17.    Actuellement, nous avons configuré la source et la cible :

18.    Sélectionnez le composant de règle et cliquez sur le bouton "Green Plus" :

19.    Sélectionnez Send (Envoyer) pour créer le composant When (Quand) :

20.    Sélectionnez le composant "When", cliquez sur le bouton "Green Plus", puis sélectionnez le composant "Send" :

21.    Vous êtes censé voir l'image affichée ci-dessous sur votre écran :

22.    Faites un double-clic sur le composant cible et définissez les éléments de configuration sur PatientSDAOperation, puis cliquez sur le bouton OK :

23.    Faites un double-clic sur le composant de transformation et définissez "Transforms" sur customsda.PatientDTL2, puis cliquez sur OK :

24.    Maintenant, vous avez vos définitions de règles prêtes :

25.    Cliquez sur le bouton "Save" et allez au menu "Interoperability" :

26.    Allez à Interoperability > List > Productions :

27.    Sélectionnez Patients2Production et cliquez sur le bouton "Open" :

28.    Nous allons lancer notre nouvelle production ! Cliquez sur le bouton "Start" :

29.    Sélectionnez PatentProcess et allez à l'onglet "Messages" pour voir les résultats (messages) :

30.    Cliquez sur un message pour voir un diagramme de séquence "Sequence Diagram" avec les résultats de la transformation :

Comme vous pouvez le constater, il s'agit d'un processus de glisser-déposer facile et entièrement visuel, qui transforme les messages personnalisés en SDA ou en d'autres formats. Pour en savoir plus, consultez les liens ci-dessous :

1.    Création d'intégrations FHIR de base avec InterSystems IRIS for Health : https://learning.intersystems.com/course/view.php?id=1959&ssoPass=1
2.    Découvrez HealthShare pour les développeurs et les intégrateurs de systèmes : https://learning.intersystems.com/course/view.php?id=26&ssoPass=1
3.    Création d'intégrations métier avec InterSystems IRIS https://learning.intersystems.com/course/view.php?id=1437&ssoPass=1
4.    Création d'intégrations de base HL7 avec InterSystems: https://learning.intersystems.com/course/view.php?id=1350&ssoPass=1

0
0 138
Article Guillaume Rongier · Mai 21, 2022 16m read

Comme nous le savons tous, Caché est une excellente base de données qui accomplit de nombreuses tâches en son sein. Cependant, que faites-vous lorsque vous avez besoin d'accéder à une base de données externe ? Une façon de le faire est d'utiliser la passerelle Caché SQL Gateway via JDBC. Dans cet article, mon objectif est de répondre aux questions suivantes pour vous aider à vous familiariser avec cette technologie et à déboguer certains problèmes courants.

Plan de travail

Avant de se plonger dans ces questions, discutons rapidement de l'architecture de la passerelle JDBC SQL Gateway. Pour simplifier, vous pouvez considérer que l'architecture est la suivante : Cache établit une connexion TCP avec un processus Java, appelé processus de passerelle. Le processus de passerelle se connecte ensuite à une base de données distante, telle que Caché, Oracle ou SQL Server, en utilisant le pilote spécifié pour cette base de données. Pour plus d'informations sur l'architecture de la passerelle SQL Gateway, veuillez consulter la documentation sur Utilisation de la passerelle Caché SQL Gateway.

Paramètres de connexion

Lorsque vous vous connectez à une base de données distante, vous devez fournir les paramètres suivants :

  • nom d'utilisateur
  • mot de passe
  • nom du pilote
  • URL
  • chemin de classe

Connexion à la base de données Caché

Par exemple, si vous avez besoin de vous connecter à une instance de Caché en utilisant la passerelle SQL Gateway via JDBC, vous devez naviguer vers [System Administration] -> [Configuration] -> [Connectivity] -> [SQL Gateway Connections] dans le portail de gestion du système (SMP). Cliquez ensuite sur "Créer une nouvelle connexion" et spécifiez "JDBC" comme type de connexion.

Lors de la connexion à un système Caché, le nom du pilote doit toujours être com.intersys.jdbc.CacheDriver, comme indiqué dans la capture d'écran. Si vous vous connectez à une base de données tierce, vous devrez utiliser un nom de pilote différent (voir Connexion à des bases de données tierces ci-dessous).

Lorsque vous vous connectez aux bases de données Caché, vous n'avez pas besoin de spécifier un chemin de classe car le fichier JAR est téléchargé automatiquement.

Le paramètre URL varie également en fonction de la base de données à laquelle vous vous connectez. Pour les bases de données Caché, vous devez utiliser une URL de la forme suivante

jdbc:Cache://[server_address]:[superserver_port]/[namespace]

Connexion à des bases de données tierces

Une base de données tierce courante est Oracle. Un exemple de configuration est présenté ci-dessous.

Comme vous pouvez le constater, le nom du pilote et l'URL ont des caractéristiques différentes de celles que nous avons utilisées pour la connexion précédente. En outre, j'ai spécifié un chemin de classe dans cet exemple, car je dois utiliser le pilote d'Oracle pour me connecter à leur base de données.

Comme vous pouvez l'imaginer, SQL Server utilise différents modèles d'URL et de noms de pilotes.

Vous pouvez tester si les valeurs sont valides en cliquant sur le bouton " Testez la connexion ". Pour créer la connexion, cliquez sur "Enregistrer".

JDBC Gateway vs le service Java Gateway Business Service

Tout d'abord, la passerelle JDBC et le service de passerelle Java sont complètement indépendants l'un de l'autre. La passerelle JDBC peut être utilisée sur tous les systèmes basés sur Caché, alors que le service de passerelle Java n'existe que dans le cadre d'Ensemble. En outre, le service de passerelle Java utilise un processus différent de celui utilisé par la passerelle JDBC. Pour plus de détails sur le service commercial de passerelle Java, veuillez consulter Le service commercial de passerelle Java.

Méthodes et outils

Vous trouverez ci-dessous 5 outils et méthodes couramment utilisés pour résoudre des problèmes avec la passerelle JDBC SQL Gateway. Je vais d'abord parler de ces outils et vous montrer quelques exemples de leur utilisation dans la section suivante.

1. Journaux

A. Journal du pilote et journal de la passerelle

Lorsque vous utilisez la passerelle JDBC, le journal correspondant est le journal de la passerelle JDBC SQL. Comme nous l'avons vu précédemment, la passerelle JDBC est utilisée lorsque Caché doit accéder à des bases de données externes, ce qui signifie que Caché est le client. Le journal du pilote, par contre, correspond à l'utilisation du pilote JDBC d'InterSystems pour accéder à une base de données Caché à partir d'une application externe, ce qui signifie que Caché est le serveur. Si vous avez une connexion d'une base de données Caché à une autre base de données Caché, les deux types de journaux peuvent être utiles.

Dans notre documentation la section relative à l'activation du journal du pilote est intitulée "Activation de la journalisation pour JDBC", et la section relative à l'activation du journal de la passerelle est intitulée "Activation de la journalisation pour la passerelle SQL JDBC".

Même si les deux journaux comportent le mot "JDBC", ils sont totalement indépendants. L'objet de cet article est la passerelle JDBC, c'est pourquoi j'aborderai plus en détail le journal de la passerelle. Pour plus d'informations sur le journal du pilote, veuillez vous reporter à la section Activation du journal du pilote.

B. Activation du journal du pilote

Si vous utilisez la passerelle Caché JDBC SQL Gateway, vous devez effectuer les opérations suivantes pour activer la journalisation : dans le portail de gestion, allez dans [System Administration] > [Configuration] > [Connectivity] > [JDBC Gateway Settings]. Indiquez une valeur pour le journal de la passerelle JDBC. Ce doit être le chemin complet et le nom d'un fichier journal (par exemple, /tmp/jdbcGateway.log). Le fichier sera automatiquement créé s'il n'existe pas, mais le répertoire ne le sera pas. Caché va démarrer la passerelle JDBC SQL Gateway avec journalisation pour vous.

Si vous utilisez le service commercial Java Gateway dans Ensemble, veuillez consulter Activation de la journalisation de la passerelle Java Gateway dans Ensemble pour savoir comment activer la journalisation.

C. Analyse du journal d'une passerelle

Maintenant que vous avez collecté un journal de passerelle, vous vous posez peut-être la question suivante : quelle est la structure du journal et comment le lire ? Bonne question ! Je vais vous fournir ici quelques informations de base pour vous aider à démarrer. Malheureusement, il n'est pas toujours possible d'interpréter complètement le journal sans avoir accès au code source. Pour les situations complexes, n'hésitez pas à contacter le WRC (Centre de réponse global d'InterSystems) !

Pour démystifier la structure du journal, rappelez-vous qu'il s'agit toujours d'un morceau de données suivi d'une description de ce qu'il fait. Par exemple, voyez cette image avec une coloration syntaxique de base :

Afin de comprendre ce que Received signifie ici, vous devez vous rappeler que le journal de la passerelle enregistre les interactions entre la passerelle et la base de données descendante. Ainsi, Received signifie que la passerelle a reçu l'information de Caché/Ensemble. Dans l'exemple ci-dessus, la passerelle a reçu le texte d'une requête SELECT. Les significations des différentes valeurs de msgId peuvent être trouvées dans le code interne. Le 33 que nous voyons ici signifie " Preparer l'instruction ".

Le journal lui-même fournit également des informations sur le pilote, ce qui est intéressant à vérifier lors du débogage des problèmes. Voici un exemple,

Comme nous pouvons le voir, le Driver Name est com.intersys.jdbc.CacheDriver, ce qui est le nom du pilote utilisé pour se connecter au processus de passerelle. Le Jar File Name est cachejdbc.jar, ce qui est le nom du fichier jar situé dans <cache_install_directory>\lib\.

2. Trouver le processus de passerelle

Pour trouver le processus de passerelle, vous pouvez exécuter la commande ps. Par exemple,

ps -ef | grep java

Cette commande ps affiche des informations sur le processus Java, notamment le numéro de port, le fichier jar, le fichier journal, l'ID du processus Java et la commande qui a lancé le processus Java.

Voici un exemple du résultat de la commande :

mlimbpr15:~ mli$ ps -ef | grep java
17182 45402 26852   0 12:12PM ??         0:00.00 sh -c java -Xrs -classpath /Applications/Cache20151/lib/cachegateway.jar:/Applications/Cache20151/lib/cachejdbc.jar com.intersys.gateway.JavaGateway 62972 /Applications/Cache20151/mgr/JDBC.log 2>&1
17182 45403 45402   0 12:12PM ??         0:00.22 /usr/bin/java -Xrs -classpath /Applications/Cache20151/lib/cachegateway.jar:/Applications/Cache20151/lib/cachejdbc.jar com.intersys.gateway.JavaGateway 62972 /Applications/Cache20151/mgr/JDBC.log
502 45412 45365   0 12:12PM ttys000    0:00.00 grep java

Dans Windows, vous pouvez consulter le gestionnaire des tâches pour trouver des informations sur le processus de passerelle.

3. Lancement et arrêt de la passerelle

Il y a deux façons de lancer et d'arrêter la passerelle :

  1. Par le biais du SMP
  2. Utilisation du terminal

A. Par le biais du SMP

Vous pouvez lancer et arrêter la passerelle dans le SMP en accédant à [System Administration] -> [Configuration] -> [Connectivity] -> [JDBC Gateway Server].

B. Utilisation du terminal

Sur les machines Unix, vous pouvez également démarrer la passerelle depuis le terminal. Comme nous l'avons vu dans la section précédente, le résultat de ps -ef | grep java contient la commande qui a démarré le processus Java, qui dans l'exemple ci-dessus est le suivant:

java -Xrs -classpath /Applications/Cache20151/lib/cachegateway.jar:/Applications/Cache20151/lib/cachejdbc.jar com.intersys.gateway.JavaGateway 62972 /Applications/Cache20151/mgr/JDBC.log

Pour arrêter la passerelle depuis le terminal, vous pouvez tuer le processus. L'ID du processus Java est le deuxième chiffre de la ligne qui contient la commande ci-dessus, dans l'exemple ci-dessus c'est 45402. Ainsi, pour arrêter la passerelle, vous pouvez exécuter :

kill 45402

4. Écrire un programme Java

Exécuter un programme Java pour se connecter à une base de données descendante est un excellent moyen de tester la connexion, de vérifier la requête et d'aider à isoler la cause d'un problème donné. Je joins un exemple de programme Java qui établit une connexion avec SQL Server et imprime une liste de tous les tableaux. J'expliquerai pourquoi cela peut être utile dans la section suivante.

import java.sql.*;
import java.sql.Date;
import java.util.*;
import java.lang.reflect.Method;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.math.BigDecimal;
import javax.sql.*;

// Auteur : Vicky Li
// Ce programme établit une connexion avec le serveur SQL et récupère tous les tableaux. Le résultat est une liste de tableaux.

public class TestConnection {
    public static void main(String[] args) {
        try {
            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
            //please replace url, username, and password with the correct parameters
            Connection conn = DriverManager.getConnection(url,username,password);

            System.out.println("connected");

            DatabaseMetaData meta = conn.getMetaData();
            ResultSet res = meta.getTables(null, null, null, new String[] {"TABLE"});
            System.out.println("List of tables: ");
            while (res.next()) {
                System.out.println(
                    "   " + res.getString("TABLE_CAT") +
                    ", " + res.getString("TABLE_SCHEM") +
                    ", " + res.getString("TABLE_NAME") +
                    ", " + res.getString("TABLE_TYPE")
                );
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Pour exécuter ce programme Java (ou tout autre programme Java), vous devez d'abord compiler le fichier .java, qui dans notre cas s'appelle TestConnection.java. Ensuite, un nouveau fichier sera généré au même endroit, que vous pourrez ensuite exécuter avec la commande suivante sur un système UNIX :

java -cp "<path to driver>/sqljdbc4.jar:lib/*:." TestConnection

Dans Windows, vous pouvez exécuter la commande suivante :

java -cp "<path to driver>/sqljdbc4.jar;lib/*;." TestConnection

5. Suivi d'une trace de jstack

Comme son nom l'indique, jstack imprime l'arborescence des appels de procédure Java. Cet outil peut devenir pratique lorsque vous avez besoin de mieux comprendre ce que fait le processus Java. Par exemple, si vous voyez le processus de la passerelle s'accrocher à un certain message dans le journal des passerelles, vous pourriez vouloir recueillir une trace jstack. Je tiens à souligner que jstack est un outil de bas niveau qui ne devrait être utilisé que lorsque d'autres méthodes, comme l'analyse du journal des passerelles, ne résolvent pas le problème.

Avant de collecter une trace jstack, vous devez vous assurer que le JDK est installé. Voici la commande pour collecter une trace jstack :

jstack -F <pid> > /<path to file>/jstack.txt

où le pid est l'ID du processus de la passerelle, qui peut être obtenu en exécutant la commande ps, telle que ps -ef | grep java. Pour plus d'informations sur la façon de trouver le pid, veuillez consulter Lancement et arrêt de la passerelle.

Maintenant, voici quelques considérations spéciales pour les machines Red Hat. Dans le passé, il y a eu des problèmes pour attacher jstack au processus de la passerelle JDBC (ainsi qu'au processus du service métier de la passerelle Java lancé par Ensemble) sur certaines versions de Red Hat, donc la meilleure façon de collecter une trace jstack sur Red Hat est de lancer le processus de la passerelle manuellement. Pour les instructions, veuillez consulter Collecter une trace jstack sur Red Hat.

Types courants de problèmes et approches pour les résoudre

1. Problème : Java n'est pas installé correctement

Dans cette situation, vérifiez la version de Java et les variables d'environnement.

Pour vérifier la version de Java, vous pouvez exécuter la commande suivante à partir d'un terminal :

java -version

Si vous obtenez l'erreur java : Command not found, cela signifie que le processus Cache ne peut pas trouver l'emplacement des exécutables Java. Cela peut généralement être résolu en plaçant les exécutables Java dans le PATH. Si vous rencontrez des problèmes, n'hésitez pas à contacter le WRC (Centre de réponse global).

2. Problème : échec de la connexion

Un bon diagnostic des échecs de connexion est la vérification du lancement du processus de la passerelle. Vous pouvez le faire en vérifiant le journal de la passerelle ou le processus de la passerelle. Sur les versions modernes, vous pouvez également aller sur le SMP et visiter [System Administration] -> [Configuration] -> [Connectivity] -> [JDBC Gateway Server], et vérifier si la page affiche "JDBC Gateway is running".

Si le processus de passerelle ne s'exécute pas, il est probable que Java n'est pas installé correctement ou que vous utilisez le mauvais port ; si le processus de passerelle s'exécute, il est probable que les paramètres de connexion sont incorrects.

Dans le premier cas, veuillez vous reporter à la section précédente et vérifiez le numéro de port. Je discuterai plus en détail de la deuxième situation ici.

Il est de la responsabilité du client d'utiliser les paramètres de connexion corrects :

  • nom d'utilisateur
  • mot de passe
  • nom du pilote
  • URL
  • chemin de classe

Vous pouvez vérifier si vous avez les bons paramètres de l'une des trois façons suivantes :

  • Utilisez le bouton "Test Connection" après avoir sélectionné un nom de connexion dans [System Administration] -> [Configuration] -> [Connectivity] -> [SQL Gateway Connections]. Note : pour les systèmes modernes, "Test Connection" donne des messages d'erreur utiles ; pour les systèmes plus anciens, le JDBC gateway log est nécessaire pour trouver plus d'informations sur l'échec.

  • Exécutez la ligne de commande suivante depuis un terminal Caché pour tester la connexion :

      d $SYSTEM.SQLGateway.TestConnection(<connection name>)
    
  • Exécutez un programme Java pour établir une connexion. Le programme que vous écrivez peut être similaire à l' example dont nous avons parlé précédemment.

3. Problème : décalage entre la façon dont Caché comprend JDBC et la façon dont la base de données distante comprend JDBC, par exemple :

  • problèmes de type de données
  • procédure stockée avec des paramètres de sortie
  • flux

Pour cette catégorie, il est souvent plus utile de travailler avec le WRC (Centre de réponse global). Voici ce que nous faisons souvent pour déterminer si le problème se situe dans notre code interne ou dans la base de données distante (ou dans le pilote) :

Remarque

Le service commercial de la passerelle Java

Le nom de la classe du Service Métier d' Ensemble est EnsLib.JavaGateway.Service, et la classe de l'adaptateur est EnsLib.JavaGateway.ServiceAdapter. La session Ensemble crée d'abord une connexion avec le serveur Java Gateway, qui est un processus Java. L'architecture est similaire à celle de la passerelle JDBC SQL, sauf que le processus Java est géré par l'opération commerciale. Pour plus de détails, veuillez consulter la documentation.

Activation du journal du pilote

Pour activer le journal du pilote, vous devez ajouter un nom de fichier journal à la fin de la chaîne de connexion JDBC. Par exemple, si la chaîne de connexion originale ressemble à czci :

jdbc:Cache://127.0.0.1:1972/USER

Pour activer la journalisation, ajoutez un fichier (jdbc.log) à la fin de la chaîne de connexion, de sorte qu'elle ressemble à ceci :

jdbc:Cache://127.0.0.1:1972/USER/jdbc.log

Le fichier journal sera enregistré dans le répertoire de travail de l'application Java.

Activation de la journalisation de la passerelle Java dans Ensemble

Si vous utilisez le service métier de la passerelle Java dans Ensemble pour accéder à une autre base de données, vous devez, pour activer la journalisation, spécifier le chemin et le nom d'un fichier journal (par exemple, /tmp/javaGateway.log) dans le champ "Log File" du service de la passerelle Java. Veuillez noter que le chemin d'accès doit exister.

N'oubliez pas que la connexion de la passerelle Java utilisée par la production Ensemble est distincte des connexions utilisées par les tableaux liés ou d'autres productions. Ainsi, si vous utilisez Ensemble, vous devez collecter le journal dans le service de passerelle Java. Le code qui démarre le service de passerelle Java utilise le paramètre "Log File" dans Ensemble, et n'utilise pas le paramètre dans la passerelle Caché SQL dans le SMP comme décrit précédemment.

Récupération d'une trace jstack sur Red Hat

La clé ici est de lancer le processus de la passerelle manuellement, et la commande pour lancer la passerelle peut être obtenue en exécutant ps -ef | grep java. Vous trouverez ci-dessous les étapes complètes à suivre pour collecter une trace jstack sur Red Hat lors de l'exécution de la passerelle JDBC ou du service métier de la passerelle Java.

  1. Assurez-vous que le JDK est installé.

  2. Dans un terminal, exécutez ps -ef | grep java. Obtenez les deux informations suivantes à partir du résultat :

    • a. Copiez la commande qui a lancé la passerelle. Cela devrait ressembler à quelque chose comme ça : java -Xrs -classpath /Applications/Cache20151/lib/cachegateway.jar:/Applications/Cache20151/lib/cachejdbc.jar com.intersys.gateway.JavaGateway 62972 /Applications/Cache20151/mgr/JDBC2.log

    • b. Obtenez l'ID du processus Java (pid), qui est le deuxième chiffre de la ligne qui contient la commande ci-dessus.

  3. Arrêtez le processus avec kill <pid>.

  4. Exécutez la commande que vous avez copiée à l'étape 2.a. pour lancer manuellement un processus de passerelle.

  5. Jetez un coup d'oeil au journal de la passerelle (dans notre exemple, il est situé dans /Applications/Cache20151/mgr/JDBC2.log) et assurez-vous que vous voyez des entrées comme >> LOAD_JAVA_CLASS: com.intersys.jdbc.CacheDriver. Cette étape est juste pour vérifier qu'un appel à la passerelle est effectué avec succès.

  6. Dans un nouveau terminal, exécutez ps -ef | grep java pour obtenir le pid du processus de la passerelle.

  7. Rassemblez une trace jstack : jstack -F <pid> > /tmp/jstack.txt

0
0 286
Article Sylvain Guilbaud · Mars 18, 2022 6m read

Dans cet article, je vais vous montrer comment vous pouvez facilement conteneuriser les passerelles .Net/Java.

Pour notre exemple, nous allons développer une intégration avec Apache Kafka.

Et pour interopérer avec le code Java/.Net, nous utiliserons PEX.

Architecture

Notre solution fonctionnera entièrement dans docker et ressemblera à ceci :

Passerelle Java

Tout d'abord, nous allons développer l'opération Java pour envoyer des messages dans Kafka. Le code peut être écrit dans l'IDE de votre choix et il peut ressembler à ceci.

En bref :

  • Pour développer une nouvelle opération commerciale PEX, nous devons implémenter la classe abstraite com.intersystems.enslib.pex.BusinessOperation
  • Les propriétés publiques sont les paramètres de l'hôte de l'entreprise
  • La méthode OnInit est utilisée pour initier la connexion à Kafka et obtenir un pointeur vers InterSystems IRIS
  • OnTearDown est utilisé pour se déconnecter de Kafka (à l'arrêt du processus)
  • OnMessage reçoit le message dc.KafkaRequest et l'envoie à Kafka

Maintenant, plaçons-le dans Docker !

Voici notre dockerfile :

FROM openjdk:8 AS builder

ARG APP_HOME=/tmp/app

COPY src $APP_HOME/src

COPY --from=intersystemscommunity/jgw:latest /jgw/*.jar $APP_HOME/jgw/

WORKDIR $APP_HOME/jar/
ADD https://repo1.maven.org/maven2/org/apache/kafka/kafka-clients/2.5.0/kafka-clients-2.5.0.jar .
ADD https://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar .
ADD https://repo1.maven.org/maven2/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar .
ADD https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.jar .

WORKDIR $APP_HOME/src

RUN javac -classpath $APP_HOME/jar/*:$APP_HOME/jgw/* dc/rmq/KafkaOperation.java && \
    jar -cvf $APP_HOME/jar/KafkaOperation.jar dc/rmq/KafkaOperation.class

FROM intersystemscommunity/jgw:latest

COPY --from=builder /tmp/app/jar/*.jar $GWDIR/

Allons-y ligne par ligne et voyons ce qui se passe ici (je suppose que vous connaissez les constructions docker à plusieurs niveaux) :

FROM openjdk:8 AS builder

Notre image de départ est JDK 8.

ARG APP_HOME=/tmp/app
COPY src $APP_HOME/src

Nous copions nos sources du dossier /src dans le dossier /tmp/app.

COPY --from=intersystemscommunity/jgw:latest /jgw/*.jar $APP_HOME/jgw/

Nous copions les sources de la passerelle Java dans le dossier /tmp/app/jgw.

WORKDIR $APP_HOME/jar/
ADD https://repo1.maven.org/maven2/org/apache/kafka/kafka-clients/2.5.0/kafka-clients-2.5.0.jar .
ADD https://repo1.maven.org/maven2/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar .
ADD https://repo1.maven.org/maven2/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar .
ADD https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.jar .

WORKDIR $APP_HOME/src

RUN javac -classpath $APP_HOME/jar/*:$APP_HOME/jgw/* dc/rmq/KafkaOperation.java && \
    jar -cvf $APP_HOME/jar/KafkaOperation.jar dc/rmq/KafkaOperation.class

Maintenant toutes les dépendances sont ajoutées et javac/jar est appelé pour compiler le fichier jar. Pour un projet concret, il est préférable d'utiliser maven ou gradle.

FROM intersystemscommunity/jgw:latest

COPY --from=builder /tmp/app/jar/*.jar $GWDIR/

Et enfin, les jars sont copiés dans l'image de base jgw (l'image de base se charge également du démarrage de la passerelle et des tâches connexes).

Passerelle .Net

Vient ensuite le service .Net qui recevra les messages de Kafka. Le code peut être écrit dans l'IDE de votre choix et il peut ressembler à ceci.

En bref :

  • Pour développer un nouveau service d'entreprise PEX nous devons implémenter la classe abstraite InterSystems.EnsLib.PEX.BusinessService
  • Les propriétés publiques sont les paramètres de l'hôte de l'entreprise
  • La méthode OnInit est utilisée pour établir une connexion avec Kafka, s'abonner à des sujets et obtenir un pointeur vers InterSystems IRIS
  • OnTearDown est utilisé pour se déconnecter de Kafka (à l'arrêt du processus)
  • OnMessage consomme les messages de Kafka et envoie des messages Ens.StringContainer aux autres hôtes d'Interoperability

Maintenant, plaçons-le dans Docker !

Voici notre dockerfile :

FROM mcr.microsoft.com/dotnet/core/sdk:2.1 AS build

ENV ISC_PACKAGE_INSTALLDIR /usr/irissys
ENV GWLIBDIR lib
ENV ISC_LIBDIR ${ISC_PACKAGE_INSTALLDIR}/dev/dotnet/bin/Core21

WORKDIR /source
COPY --from=store/intersystems/iris-community:2020.2.0.211.0 $ISC_LIBDIR/*.nupkg $GWLIBDIR/

# copier csproj et restaurer en tant que couches distinctes
COPY *.csproj ./
RUN dotnet restore

# copier et publier l'application et les bibliothèques
COPY . .
RUN dotnet publish -c release -o /app

# étape/image finale
FROM mcr.microsoft.com/dotnet/core/runtime:2.1
WORKDIR /app
COPY --from=build /app ./

# Configurations pour démarrer le serveur passerelle
RUN cp KafkaConsumer.runtimeconfig.json IRISGatewayCore21.runtimeconfig.json && \
    cp KafkaConsumer.deps.json IRISGatewayCore21.deps.json

ENV PORT 55556

CMD dotnet IRISGatewayCore21.dll $PORT 0.0.0.0

Allons-y ligne par ligne :

FROM mcr.microsoft.com/dotnet/core/sdk:2.1 AS build

Nous utilisons le SDK complet .Net Core 2.1 pour construire notre application.

ENV ISC_PACKAGE_INSTALLDIR /usr/irissys
ENV GWLIBDIR lib
ENV ISC_LIBDIR ${ISC_PACKAGE_INSTALLDIR}/dev/dotnet/bin/Core21

WORKDIR /source
COPY --from=store/intersystems/iris-community:2020.2.0.211.0 $ISC_LIBDIR/*.nupkg $GWLIBDIR/

Copiez .Net Gateway NuGets de l'image Docker officielle d'InterSystems dans notre image de constructeur

# copier csproj et restaurer comme couches distinctes
COPY *.csproj ./
RUN dotnet restore

# copier et publier l'application et les bibliothèques
COPY . .
RUN dotnet publish -c release -o /app

Construisez notre bibliothèque.

# étape/image finale
FROM mcr.microsoft.com/dotnet/core/runtime:2.1
WORKDIR /app
COPY --from=build /app ./

Copiez les dll de la bibliothèque dans le conteneur final que nous exécuterons réellement.

# Configurats pour démarrer le serveur Gateway
RUN cp KafkaConsumer.runtimeconfig.json IRISGatewayCore21.runtimeconfig.json && \
    cp KafkaConsumer.deps.json IRISGatewayCore21.deps.json

Actuellement, la passerelle .Net doit charger toutes les dépendances au démarrage, nous lui faisons donc connaître toutes les dépendances possibles.

ENV PORT 55556

CMD dotnet IRISGatewayCore21.dll $PORT 0.0.0.0

Démarrez la passerelle sur le port 55556 en écoutant sur toutes les interfaces.

Et voilà, c'est tout !

Voici un docker-compose complet pour que tout fonctionne (y compris Kafka et Kafka UI pour voir les messages).

Pour exécuter la démo, vous dever :

  1. Installer :
  2. Exécuter :
git clone https://github.com/intersystems-community/pex-demo.git cd pex-demo docker-compose pull docker-compose up -d

 

Avis important : Les bibliothèques Java Gateway et .Net Gateway DOIVENT provenir de la même version que le client InterSystems IRIS.

0
0 229