go to post André-Claude Gendron · Dec 4 But if you add this flag, you will loose valuable tuned-table information perhaps ran on a system with a representative dataset. <AverageFieldSize>9.62</AverageFieldSize> <Selectivity>0.7246%</Selectivity> <BlockCount>-12</BlockCount> OutlierSelectivity also is nice but contains "real data" and should be avoided. On our end we plan to run a "linting" script after exportation but before commit to keep valuable stats but omit the data itself (such as the one in the histogram). Does this seems like a good way to do it ?
go to post André-Claude Gendron · May 13, 2024 That would work and is a clean solution. This is what I expected from the the framework.
go to post André-Claude Gendron · May 10, 2024 I appreciate the suggestion. However this would only work for a JSON Export and not a JSON Import.
go to post André-Claude Gendron · Apr 11, 2024 Here we are using the mocking framework that we developed (GitHub - GendronAC/InterSystems-UnitTest-Mocking: This project contains a mocking framework to use with InterSystems' Products written in ObjectScript Have a look at the https://github.com/GendronAC/InterSystems-UnitTest-Mocking/blob/master/S... class. Instead of calling ..SendRequestAsync we do ..ensHost.SendRequestAsync(...) Doing so enables us to create Expectations (..Expect(..ensHost.SendRequestAsync(.... Here a code sample : Class Sample.Src.CExampleService Extends Ens.BusinessService { /// The type of adapter used to communicate with external systems Parameter ADAPTER = "Ens.InboundAdapter"; Property TargetConfigName As %String(MAXLEN = 1000); Parameter SETTINGS = "TargetConfigName:Basic:selector?multiSelect=0&context={Ens.ContextSearch/ProductionItems?targets=1&productionName=@productionId}"; // -- Injected dependencies for unit tests Property ensService As Ens.BusinessService [ Private ]; /// initialize Business Host object Method %OnNew( pConfigName As %String, ensService As Ens.BusinessService = {$This}) As %Status { set ..ensService = ensService return ##super(pConfigName) } /// Override this method to process incoming data. Do not call SendRequestSync/Async() from outside this method (e.g. in a SOAP Service or a CSP page). Method OnProcessInput( pInput As %RegisteredObject, Output pOutput As %RegisteredObject, ByRef pHint As %String) As %Status { set output = ##class(Ens.StringContainer).%New("Blabla") return ..ensService.SendRequestAsync(..TargetConfigName, output) } } Import Sample.Src Class Sample.Test.CTestExampleService Extends Tests.Fw.CUnitTestBase { Property exampleService As CExampleService [ Private ]; Property ensService As Ens.BusinessService [ Private ]; ClassMethod RunTests() { do ##super() } Method OnBeforeOneTest(testName As %String) As %Status { set ..ensService = ..CreateMock() set ..exampleService = ##class(CExampleService).%New("Unit test", ..ensService) set ..exampleService.TargetConfigName = "Some test target" return ##super(testName) } // -- OnProcessInput tests -- Method TestOnProcessInput() { do ..Expect(..ensService.SendRequestAsync("Some test target", ..NotNullObject(##class(Ens.StringContainer).%ClassName(1))) ).AndReturn($$$OK) do ..ReplayAllMocks() do $$$AssertStatusOK(..exampleService.OnProcessInput()) do ..VerifyAllMocks() } Method TestOnProcessInputFailure() { do ..Expect(..ensService.SendRequestAsync("Some test target", ..NotNullObject(##class(Ens.StringContainer).%ClassName(1))) ).AndReturn($$$ERROR($$$GeneralError, "Some error")) do ..ReplayAllMocks() do $$$AssertStatusNotOK(..exampleService.OnProcessInput()) do ..VerifyAllMocks() } }
go to post André-Claude Gendron · Nov 15, 2023 We are sending SMS to Twilio through a generic http operation in an Ensemble Production. Works well. We wrote a simple Process that catches HTTP 429 errors (their API documentation has a requirement about this).
go to post André-Claude Gendron · May 10, 2023 You could have a 0 day Ens.Util.Purge task running every 5 mins and clearing the production messages. That way you could use only built-in components such as the hl7 tcp service and hl7 file operation
go to post André-Claude Gendron · Apr 12, 2023 ClassMethod GetContentJSON() { set xData = ##class(%Dictionary.CompiledXData).%OpenId(..%ClassName(1) _ "||Content") set jsonObj = [].%FromJSON(xData.Data) write jsonObj.%ToJSON() } XData Content [ MimeType = application/json ] { [[12,33], [88,44]] }
go to post André-Claude Gendron · Nov 25, 2022 Here are a few code samples that could help : Class YourPackage.REST.CSoapAuthenticator Extends %CSP.REST { Parameter CONTENTTYPE = "text/xml"; XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ] { <Routes> <Route Url="/:soapService" Method="POST" Call="PostSOAP"/> </Routes> } ClassMethod PostSOAP( strSoapService As %String = "", test As %Integer = 0) As %Status { #Dim %request As %CSP.Request #Dim %response As %CSP.Response #Dim httpClient As %Net.HttpRequest = ..GetLoopbackSOAPClient() do httpClient.EntityBody.Write(..UpdateSoapBody(%request.Content.Read($$$MaxStringLength))) do httpClient.SetHeader("SOAPAction", %request.SoapAction) do httpClient.Post($System.CSP.GetDefaultApp($Namespace) _ "/" _ strSoapService, test) set %response.ContentType = "text/xml" write httpClient.HttpResponse.Data.Read($$$MaxStringLength) return $$$OK } // -- Private utils -- ClassMethod GetLoopbackSOAPClient() As %Net.HttpRequest [ Private ] { set httpClient = ##class(%Net.HttpRequest).%New() set httpClient.Server = ... set httpClient.Port = ... set httpClient.Timeout = 5 set httpClient.Https = 1 set httpClient.SSLConfiguration = ... return httpClient } ClassMethod UpdateSoapBody(strInput As %String) As %String [ Private ] { #Dim strSoap As %String = "" #Dim username As %String = ... (Extract from Input) #Dim password As %String = ... (Extract from Input) set strSoap = strSoap _ ... (Copy soap enveloppe from input) set strSoap = strSoap _ " <soap:Header>" _ ..GenerateSecurityHeader(username, password) _ " </soap:Header>" set strSoap = strSoap _ " <soap:Body>" ... set strSoap = strSoap _ " </soap:Body>" set strSoap = strSoap _ "</soap:Envelope>" return strSoap } ClassMethod GenerateSecurityHeader( strUsername As %String, strPassword As %String) As %String [ Private ] { set header = ##class(%SOAP.Security.Header).%New() set usernameToken = ##class(%SOAP.Security.UsernameToken).Create(strUsername, strPassword) do header.AddSecurityElement(usernameToken) return ... (Use XML Writer to Output header to a String.) } }
go to post André-Claude Gendron · Nov 16, 2022 I ended-up creating a %CSP.Rest class that acts as a proxy which reordered the fields in order to generate a standard SOAP request with the proper headers. Works great for a minimum of code.
go to post André-Claude Gendron · May 13, 2022 I just remembered, I fixed this but was waiting for a review. I merged it this morning. https://github.com/GendronAC/InterSystems-UnitTest-Mocking/pull/3 (code was sent to github per InterSystems request) Latest code is here : https://github.com/GendronAC/InterSystems-UnitTest-Mocking Let me know if you need something else. Have a look at the CTestCustomPassthroughOperation.cls class
go to post André-Claude Gendron · May 13, 2022 Yes the mocking framework is still under active development here. I'm sorry there are missing classes in the provided example. I'll completely forgot about my reply a year ago... Yes testing business hosts works very well with it. I'll try to arrange something today and I'll reply here. If I don't, reply back !
go to post André-Claude Gendron · Sep 15, 2021 Is is still recommended to separate the Globals and Routines ? What's the major benefit of it ? Rapid deployment by switching the Routine database ?
go to post André-Claude Gendron · Jun 18, 2021 I would be very much interested in your findings. I already started something that is producing a CSV file with a summary of a production. Perhaps this could be helpful to the community, contact me in private since I can't attach a file. This is not ment for Archi mate but perhaps you can be inspired by it.
go to post André-Claude Gendron · May 26, 2021 Sorry about that, I will commit them in the next few days or perhaps tonight. At the time they were not added to the repo because of dependencies but I'm sure I can arrange something. Plus I'll add the latest development we did at CIUSSSE-CHUS. I'm glad someone else uses it ! Kind regards, AC
go to post André-Claude Gendron · Oct 14, 2020 I know this is an old post and I don't expect a reply but is there a way to enable SNI or are the headers added by default ?
go to post André-Claude Gendron · Feb 26, 2019 Thank you, I will have a look at that and also, I'm replicating my setup on a redhat gitlab-runner. I'll update this post if I find my way out of this on Windows. I also noticed that the "ENVIRONMENT" variables were not passed appropriately in a way that csession understands. The $system.Util.GetEnviron("CI_PROJECT_DIR") and $system.Util.GetEnviron("CI_COMMIT_SHA") calls both returns an empty string. Perhaps the <NOTOPEN> is related to the way the stdout is read in windows.