TAZ.R · May 9 go to post

Hi Luis,
Thank you for your reply.
I tried to the following Business Process but I still does not work.
Did I understand well your reply ?

AgendaOut being my BO (EnsLib.File.PassthroughOperation ; EnsLib.File.OutboundAdapter)
FHIRINTEROPPKG.HL7toRawJSON2 being my DTL transforming a HL7 Input to a Demo.MyApp.Messages.JSONEvent5 target class.
I have tried to use my production with this Business Process but I am encountering an issue at the Business Operation step :

Eduard, I also tried to import your method and use it in my business process but it did not work as well... Maybe i'm using it wrong? That is why I tried to do as mentioned just above by using %JSONExportToStream since I knew that my DTL produces a target class that Extends JSON Adaptor.
Thank you four help,
Kind regards

TAZ.R · May 12 go to post

Quick update on the situation.
Instead of using an assign to use %JSONExportToStream I used a code action :

Then I have dispatched the whole Ens.StreamContainer "context.streamContainer" instead of the stream itself context.streamContainer.stream
And I finally managed to write the in the output file !!!


I'm not sure i'm doing it the best way but it worked!
Should I improve my whole production or is it OK the way it is ?
Kind regards!

TAZ.R · Aug 6 go to post

Hi @Sylvain Guilbaud,
Thank you for your reply.
Basically you're saying that I need to store the secrets in a global at IRIS startup using a %ZSTART routine so I can retrieve them in a business operation, am I right ?
I have tried to do so with this routine :
 

ROUTINE %ZSTARTQUIT; 

SYSTEM
  Set^IRIS.Temp("Secrets", "APIclientid") = $System.Util.GetEnviron("APIclientid")
  Set^IRIS.Temp("Secrets", "APIclientsecret") = $System.Util.GetEnviron("APIclientsecret")

  QUIT

I have loaded it in the %SYS namespace and I can check that it has been successfuly imported when I go on the Management Portal -> System Explorer -> Routines.
Then, I set my credentials in my business operation this way to use then in a HTTP request :
 

Set APIclientid = $Get(^IRIS.Temp("Secrets", "APIclientid "),"")
Set APIclientsecret =  $Get(^IRIS.Temp("Secrets", "APIclientsecret"),"")

However, when I want to test my production, it does not seem to work, APIclientID and APIclientsecret still return empty values (while $System.Util.GetEnviron("APIclientid") returns the expected value)
Am I doing something wrong ?
Kind regards,

TAZ.R · Aug 6 go to post

Hi Sylvain.
In System  > Globals  > View Global Data > ^IRIS.Temp global I can see :
 

1:  ^IRIS.Temp("Secrets","clientid") = ""
2:  ^IRIS.Temp("Secrets","clientsecret") = ""


The %ZSTART seems to work but not retrieving the values.
You will find just below the Business Operation that tries to use the clientid and clientsecret :

Class HTTP.PostOperation.GetToken Extends Ens.BusinessOperation
{
    Parameter ADAPTER = "EnsLib.HTTP.OutboundAdapter";Parameter SETTINGS = "clientid, clientsecret, databasereference, audience, granttype, server";// Paramètres configurables depuis la production/// Adresse du serveur cible Property server As%String;/// Identification du credential clientid à utiliser pour faire la requête vers l'APIProperty clientid As%String;/// Identification du credential clientsecret à utiliser permettant la requête vers l'APIProperty clientsecret As%String;/// audience permettant la requête vers l'APIProperty audience As%String;/// référence de la database associée à l'établissement de santé concernéProperty databasereference As%String;/// granttype permettant la requête vers l'APIProperty granttype As%String [ InitialExpression = "client_credentials" ];

    Method OnMessage(pRequest As HTTP.request, Output pResponse As HTTP.response) As%Status
    {
        Set pResponse = ##class(HTTP.response).%New()
        /// 1. Purge des anciens tokens expirésDo##class(INTEROP1.TokenCache).PurgeExpired()

        /// 2. Vérifie si un token valide est déjà en cacheSet token = ""Set success = ##class(INTEROP1.TokenCache).GetValidToken("TokenCache", .token)
        If success {
            Write"Token récupéré depuis le cache", !
            Set pResponse.Token = token
            Set pResponse.Log = "Token récupéré depuis le cache"Quit$$$OK
        }

        Write"Aucun token valide trouvé, appel HTTP en cours...", !

        /// 3. Appel HTTP POST pour récupérer un nouveau tokenSet httpRequest = ##class(%Net.HttpRequest).%New()
        Set httpRequest.Server = ..serverSet httpRequest.Https = 1Set httpRequest.SSLConfiguration = "default"Set httpRequest.ContentType = "application/json"// Construction du corps de la requêteSet jsonObject = ##class(%DynamicObject).%New()
        /// Si injection env. variable Set clientid = $Get(^IRIS.Temp("Secrets", "APIclientid"),"")
        Set clientsecret = $Get(^IRIS.Temp("Secrets", "APIclientsecret"),"")
        /// Set clientid = $System.Util.GetEnviron("APIclientid")     /// Set clientsecret = $System.Util.GetEnviron("APIclientsecret")    Do jsonObject.%Set("client_id", clientid)
        Do jsonObject.%Set("client_secret", clientsecret)
        Do jsonObject.%Set("audience", ..audience)
        Do jsonObject.%Set("grant_type", ..granttype)
        Do jsonObject.%Set("database_reference", ..databasereference)

        Set requestPayload = jsonObject.%ToJSON()
           
        Do httpRequest.EntityBody.Write(requestPayload)

        Set status = httpRequest.Post("//v1/token")

        If$$$ISERR(status) {
            Write"Erreur durant l'appel HTTP", !
            Quit status
        }

        /// 4. Lecture de la réponseSet rawJSON = httpRequest.HttpResponse.Data.Read()
        Set jsondyn = ##class(%DynamicObject).%FromJSON(rawJSON)
        Set token = jsondyn.%Get("access_token")
        Set expiresIn = jsondyn.%Get("expires_in")

        Set pResponse.RawJSON = rawJSON
        Set pResponse.json = jsondyn
        Set pResponse.Token = token

        /// 5. Enregistre le token dans la base avec expirationDo##class(INTEROP1.TokenCache).SaveToken("TokenCache", token, expiresIn)
        If pResponse.Token '= ""Write"Nouveau token stocké dans le cache", !
            Set pResponse.Log = "Nouveau token stocké dans le cache"If pResponse.Token = ""Write"Impossible de récupérer le token", !
            Set pResponse.Log = "Impossible de récupérer le token"Quit$$$OK
    }
}

FYI, I have also tried this in the terminal and it does not seem to work :
(Before doing so, I tried to add a new line in the %ZSTART :

Set^IRIS.Temp("Secrets","TEST") = "Hello"
%SYS>do^%ZSTART%SYS>zw^IRIS.Temp("Secrets")
^IRIS.Temp("Secrets","TEST")="Hello"^IRIS.Temp("Secrets","lifenclientid")=""^IRIS.Temp("Secrets","lifenclientsecret")=""

The environment variables have been setup in my docker container and can be found in the docker-compose.yml :
 

....
Env": [
			"APIclientid=testclientid",
			"APIclientsecret=testclientsecret",
			"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/irisowner/bin",
			"ISC_PACKAGE_IRISGROUP=irisowner",
			"ISC_PACKAGE_IRISUSER=irisowner",
			"ISC_PACKAGE_MGRGROUP=irisowner",
			"ISC_PACKAGE_MGRUSER=irisowner",
			"IRISSYS=/home/irisowner/irissys",
			"TINI_VERSION=v0.19.0",
			"ISC_PACKAGE_INSTANCENAME=IRIS",
			"ISC_PACKAGE_INSTALLDIR=/usr/irissys",
			"PYTHONPATH=/usr/irissys/mgr/python",
			"LANG=en_US.UTF-8",
			"LANGUAGE=en_US.UTF-8",
			"LC_ALL=en_US.UTF-8"
		],
....

Maybe I have not correctly setup the environment variable and this is why this is not working ?
Kind regards,
 

TAZ.R · Aug 7 go to post

Hi @Sylvain Guilbaud 
Actually that is just a small typo, I have forgotten to replace it with APIclientid and APIclientsecret in this community post... 😁
I will look into your example right now.
Kind regards

TAZ.R · Aug 7 go to post

@Sylvain Guilbaud 
I decided to deploy a new container and set up new environment variables.
I have then setup my %ZSTART and it is now working.
I don't really understand why.
The only difference is that I have changed the variable environment names...
Thank you for your help

TAZ.R · Aug 7 go to post

@Sylvain Guilbaud,
Yes indeed. With this new instance, the SYSTEM.Util.GetEnviron("API_CLIENT_ID") works within a Business Operation.
The environment variable is now available for every business operation.
I don't even need to use %ZSTART.
I hope I will one day understand why it works now!
Thank you for your help.