go to post Laura Blázquez ... · 14 hr ago I don't know if this apply, but I have written an article about the application. And I have translated it. Also, I have seen that I have 2 points for finding FHIR bug, but I think I don't have found any 😅
go to post Laura Blázquez ... · May 29 Sure! FHIRCraft is built using InterSystems IRIS for Health and works through an interoperability production. When you send a request (e.g. from the web UI), it goes through a REST service that transforms the input JSON into an IRIS message. From there, a business process handles the generation logic. Depending on the configuration, it can reuse existing resources from a FHIR repository or generate new ones. The generated resources (like Patient, Observation, etc.) are optionally posted back to a FHIR server — either the default IRIS repository or any external one via REST. It’s modular and easy to extend with new resource types. If you're curious, I wrote a short technical walkthrough here 😉
go to post Laura Blázquez ... · May 21 Wow, thank you very much for this full explanation!! Now I understand better how BPL's work 😊
go to post Laura Blázquez ... · May 19 I reuse object that I get on first transformation and I transform it to another object, after a call. This is the BPL that I use: Class test.bp.TestProcess Extends Ens.BusinessProcessBPL { Storage Default { <Type>%Storage.Persistent</Type> } /// BPL Definition XData BPL [ XMLNamespace = "http://www.intersystems.com/bpl" ] { <process language='objectscript' request='Ens.Request' response='Ens.Response' height='2100' width='2000' > <context> <property name='dataRsp' type='test.msg.GetDataResponse' instantiate='0' /> <property name='patient' type='HS.FHIR.DTL.vR4.Model.Resource.Patient' instantiate='0' /> <property name='fhirRsp' type='test.msg.SendResponse' instantiate='0' /> <property name='otherPatient' type='HS.FHIR.DTL.vR4.Model.Resource.Patient' instantiate='0' /> </context> <sequence xend='200' yend='800' > <code name='LOGASSERT 1' xpos='200' ypos='250' > <![CDATA[ $$$LOGASSERT("1. Get data")]]> </code> <call name='GetData' target='TestBo' async='0' xpos='200' ypos='350' > <request type='test.msg.GetDataRequest' > </request> <response type='test.msg.GetDataResponse' > <assign property="context.dataRsp" value="callresponse" action="set" languageOverride="" /> </response> </call> <code name='LOGASSERT 2' xpos='335' ypos='600' > <![CDATA[ $$$LOGASSERT("2. Transform to FHIR")]]> </code> <transform name='Transform 1' class='test.dtl.DataToPatient' source='context.dataRsp' target='context.patient' xpos='335' ypos='700' /> <code name='LOGASSERT 3' xpos='335' ypos='800' > <![CDATA[ $$$LOGASSERT("3. Send to FHIR Repo 1")]]> </code> <call name='Send to FHIR Repo 1' target='TestBo' async='0' xpos='335' ypos='900' > <request type='test.msg.SendRequest' > <assign property="callrequest" value="##class(test.Util).generatePostFHIRReq(context.patient)" action="set" languageOverride="" /> </request> <response type='test.msg.SendResponse' > </response> </call> <code name='LOGASSERT 4' xpos='470' ypos='1150' > <![CDATA[ $$$LOGASSERT("4. Transform to FHIR again (for other repo)")]]> </code> <!-- <transform name='REPEAT: Transform 1' class='test.dtl.DataToPatient' source='context.dataRsp' target='context.patient' xpos='335' ypos='700' /> --> <transform name='Transform 2' class='test.dtl.DataToOtherPatient' source='context.patient' target='context.otherPatient' xpos='470' ypos='1350' /> <code name='LOGASSERT 5' xpos='470' ypos='1450' > <![CDATA[ $$$LOGASSERT("5. Send to FHIR Repo 2")]]> </code> <call name='Send to FHIR Repo 2' target='TestBo' async='0' xpos='470' ypos='1550' > <request type='test.msg.SendRequest' > <assign property="callrequest" value="##class(test.Util).generatePostFHIRReq(context.otherPatient)" action="set" languageOverride="" /> </request> <response type='test.msg.SendResponse' > </response> </call> </sequence> </process> } } There is a commented line. If I activate this line (basically, repeat first transformation), then everything works. The generatePostFHIRReq method: ClassMethod generatePostFHIRReq(fhir As HS.FHIR.DTL.vR4.Model.Base.DomainResource) As test.msg.SendRequest { #dim fhirReq As test.msg.SendRequest set fhirReq = ##class(test.msg.SendRequest).%New() set fhirReq.url = "/"_fhir.resourceType set fhirReq.body = ##class(%Stream.GlobalCharacter).%New() do fhirReq.body.Write(fhir.ToJSON().Read()) return fhirReq } What I need is to send a FHIR resource to 2 different FHIR repositories. And for the second one I need to change some properties from de first transformation. I want to reuse the object obtained in first transformation, because sometimes the resource fot both FHIR repositories is the same.
go to post Laura Blázquez ... · May 8 That property doesn't exists in the class you are using as context. But in the rule editor, General tab, you have a section called Temporary Variables, you can create there, and reference it with @<name> in the rule. In your case, your assing will be: assing @Namespace = Piece(AlertRequest.SourceConfigName,"|") Here is the documentation: Temporary Variables User-specified temporary variables, which you can use in the rule definition. The variables must be separated by commas, for example: FreeShippingValue,ShipMethod,PremierMember You can reference a temporary variable in a rule definition by preceding the variable name with the @ (at sign) character, for example, @FreeShippingValue. You cannot use temporary variables outside the rule definition. To pass information to a transformation, you can instead use the RuleUserData property. For more information, see Selecting the Transformation and Target of a Send Action.
go to post Laura Blázquez ... · May 8 The name of the properties you are searching for are camel case, you need to change values used in "if" condition: set itr = responseData.%GetIterator() while itr.%GetNext(.key, .value) { if key = "pureId"{ set pResponse.pureID = value } elseif key = "portalUrl" { set pResponse.portalURL = value } }
go to post Laura Blázquez ... · Apr 29 I have been testing this new UI and, like I said in this post, as a developer, changes for us are very difficult, so, I apologize for my complaints, but here they are: I think the UI has too much information and elements are too small. Nowadays we have big screens, and there is a lot of space, but having all elements too close makes very difficult to see anything clearly. Everything has the same colour, it's difficult to distinguish elements, menus, etc. In the current version, when a production or an element is ON, you can see it very easy. But now, at least in my case, I can't see when an element is active, or disabled. The right menu, for the settings, having white background and everything together, makes difficult to see where a configuration starts and where it ends. The same with dropdown menus, they are white, and they blurs into the background I know that a change is needed, and I will adapt myself. But I think that with a few little improvements, this new UI can be a very good tool for all of us 😊
go to post Laura Blázquez ... · Apr 29 Totally agree. One of the points that botherer me was the small size of all the elements, and the same colours in all the interface. I have the same opinion: less is more. And I think the new UI has too much information. Like Jeffrey, I can't understand the rename of Services and Operations. And I don't understand neither why now you can disable or stop an element (maybe this option existed before, but I didn't realize until know 😅). There are other points that I don't like: I can't see when a production is ON or not. Neither the elements inside the production. In the current version, you can see this with strong colours, but now, at least in my case, I can't see it In right menu, I can't distinguish configurations. They are all with white background, and too together, so I can't see when a config starts and when ends. The same happens with dropdown menus. They are white too, so it's difficult to see things correctly. As a developer, changes are difficult to me, but I know that they are necessary. I'm not against this change, but I think with a few little improvements, it would be much better.
go to post Laura Blázquez ... · Apr 8 According to the documentation, there is a parameter "pFormat" that has default value acelo, where: c - output the ObjectScript-specific "_class" and "_id" properties So, if you just call the transform like this, it should work: set dynObj = ##class(%ZEN.Auxiliary.altJSONProvider).%ObjectToAET(person, , , "aelo")
go to post Laura Blázquez ... · Apr 8 Congratulations to everyone!! You have created so great applications 😉
go to post Laura Blázquez ... · Mar 28 After executing your query, you need to move cursor and then you can get data: SET SC = resultset.Prepare(sql) SET SC = resultset.Execute() if (resultset.Next(.SC)) { quit:$$$ISERR(SC) set cnt = resultset.Data("CNT") } SET SC = resultset.Close()
go to post Laura Blázquez ... · Mar 11 Thanks a lot for all your support! It's been a pleasure to participate 😊 And congratulations to everyone! I think it was a tough competition, all articles were so great!
go to post Laura Blázquez ... · Feb 24, 2020 I have to convert the public key from pkcs#8 to pkcs#1. I have followed this article: https://community.intersystems.com/post/format-public-key-when-using-rsaencrypt-method-systemencryption-or-systemencryptionrsaencrypt Now I can encrypt the string, but the service returns that the api_key must be given in the request. I almost have it.
go to post Laura Blázquez ... · Feb 20, 2020 I have checked that question, but I don't understand what happens. Finally I have used this instruction "openssl rsautl -in fileIn.txt -out fileOut-enc.txt -pubin -inkey public.key -encrypt" using $ZF(-100) and having OpenSSL installed on the server and it works. I want to do it with Encryption methods, there must be a way to do this with COS and not using shell instructions, right?
go to post Laura Blázquez ... · Feb 19, 2020 Sorry, I got the error with RSAGetLastError(). Is this: error:0906D06C:PEM routines:PEM_read_bio:no start line;
go to post Laura Blázquez ... · Feb 19, 2020 Thank you very much for your answer. I don't know what algorithm uses openssl_public_encrypt. I've tried this: set json = "{""api_key"":""XXXXX"", ""id"":""1""}"set file = ##class(%FileCharacterStream).%New()set file.Filename = "public.key"set key = file.Read(file.Size) set jsonEncrypt = $System.Encryption.RSAEncrypt(json, key) But it doesn't work, it returns an empty string. I try to see the error using RSAGetLastError() and I don't get anything. The public.key has this format: -----BEGIN PUBLIC KEY-----........................-----END PUBLIC KEY----- The line breaks are LF and it is in UTF-8. What format should the public key be in order to work in Ensemble? I am doing something wrong?
go to post Laura Blázquez ... · Nov 12, 2019 Thank you very much, I was able to solve my problem with what I put in, and for now I have not needed more
go to post Laura Blázquez ... · Jul 23, 2018 Thank you very much! It works! I haven't seen that button :)