go to post Jeffrey Drumm · May 16, 2023 According to a StackOverflow thread I just read, the connection url below is purported to work on Linux and authenticate with the MS JDBC driver: jdbc:sqlserver://[server]:[port];database=[db];trustServerCertificate=true;integratedSecurity=true;user=[user without domain];password=[pw];authenticationScheme=NTLM;domain=[domain];authentication=NotSpecified
go to post Jeffrey Drumm · May 5, 2023 Ok, answering my own question ... Ens.MonitorService calls the macro $$$SetHostMonitor() when the InactivityTimeout is reached, which does this: Set $$$EnsHostMonitorRoot($namespace,%host,%prop)=%val,$$$EnsHostMonitorRoot($namespace,%host,$$$eMonitorLastActivity)=$$$timeUTC And that certainly appears to be updating the LastActivity time.
go to post Jeffrey Drumm · May 3, 2023 ISCAgent is running on primary, alternate and arbiter? It has to be running on all 3. IRIS Windows installation by default will install ISCAgent but will not enable it for auto-start.
go to post Jeffrey Drumm · May 2, 2023 If you set the ENSLIB database to mount read/write, it will compile. I'm wondering if, after recompilation, it will work ...
go to post Jeffrey Drumm · May 1, 2023 I couldn't even get that class to compile until I set the ENSLIB database to mount R/W. And yes, I was attempting to compile it in a conventional "interoperability-enabled" namespace. That's on I4H 2022.2, fyi. Does it compile without error on your system?
go to post Jeffrey Drumm · Apr 27, 2023 Web services normally use an HTTP status code; for example, an ACK would be 200 OK for REST/HTTP and would be available through the %Net.HttpResponse Object in the StatusCode/StatusLine properties. SOAP usually provides some sort of payload along with the status code, and that would be found in the Data property. The type of response would likely be identified in the source/target system's WSDL for the SOAP interface.
go to post Jeffrey Drumm · Apr 26, 2023 This is something I wrote a long time ago; it extracts all business hosts and their settings. I've learned some things since I wrote it and would probably do a few things differently these days. It should be enough to give you some ideas, though ... ClassMethod GetConfigs(pProduction As %String = {$G(^Ens.Runtime("Name"),$G(^Ens.Suspended,$G(^Ens.Configuration("csp","LastProduction"))))}, pFile As %String = {$System.Util.GetEnviron("HOME")_"/"_$NAMESPACE_"_hostconfigs.csv"}) As %Status { Set tPrd = ##class(Ens.Config.Production).%OpenId(pProduction) Set tOut = ##class(%File).%New() Set tOut.Name = pFile Set tSC = tOut.Open("RWN") if '$$$ISERR(tSC) { Set tSC = vOut.WriteLine("""Type"",""Name"",""ClassName"",""Adapter"",""Enabled"",""ConfigName"",""ConfigValue""") } Quit:$$$ISERR(tSC) tSC If $ISOBJECT(tPrd) { For i=1:1:tPrd.Items.Count() { Set tHost = tPrd.Items.GetAt(i) Set tName = tHost.Name Set tClassName = tHost.ClassName Set tType = $CASE(tHost.BusinessType(),0:"Unknown",1:"Service",2:"Process",3:"Operation",4:"Actor",:"Huh?") Set tAdapter = $CLASSMETHOD(tClassName,"%GetParameter","ADAPTER") Set tEnabled = tHost.Enabled Set tCategory = tHost.Category Set tLine = """"_tType_""","""_tName_""","""_tClassName_""","""_tAdapter_""","""_tEnabled_""",""" Do tOut.WriteLine(tLine_"Category"","""_tCategory_"""") For l=1:1:tHost.Settings.Count() { Set tCfg = tHost.Settings.GetAt(l) Set tCfgName = tCfg.Name Set tCfgVal = tCfg.Value Set tSC = vOut.WriteLine(tLine_tCfgName_""","""_tCfgVal_"""") Return:$$$ISERR(tSC) tSC } } Do tOut.Close() } Else { Return $$$ERROR(0,"Production Not Found in this namespace") } Return $$$OK }
go to post Jeffrey Drumm · Apr 26, 2023 The error in your previous post seems to indicate that no filename was available for creating or appending. The path shown in the error does not include a filename.
go to post Jeffrey Drumm · Apr 24, 2023 If the outbound operation is configured to use %f as the filename and has the Overwrite checkbox unchecked, the output file will have the same name and all records from the input file. You mostly likely will have the input service and output operation set for different directories. Relying on the source file name may prove to be problematic if the inbound file has the same name every time it's received.
go to post Jeffrey Drumm · Apr 24, 2023 I assumed there would be a way to accomplish this with a form of OS/Delegated authentication, but I may be wrong. It wouldn't be the first time EDIT: Let me amend that. OS authentication works only for users whose OS accounts exist in IRIS, right? So don't create any IRIS users that have matching OS accounts ... With the exception of the account that needs OS authentication.
go to post Jeffrey Drumm · Apr 23, 2023 @Padmaja Konduru's solution works from the IRIS/Caché prompt when in the proper namespace. If you need to be able to script this from the OS, there will be additional steps required, such as piping command input to iris session <instance> from the OS shell. You will likely need to include a username and password in the piped input, which is generally not a good idea. Enabling OS authentication may be an option, but that's a global setting and not (easily) configurable per-user.
go to post Jeffrey Drumm · Apr 20, 2023 While $$$FormatText() is a great tool, I'd give my left ... uh, leg to have a sprintf() workalike that handles left/right justification, padding, number precision formatting, date element tokens, etc. I guess we'll just have to make do with Python f-strings ...
go to post Jeffrey Drumm · Apr 20, 2023 Theoretically, yes. HCC supports ODBC access as of August 2022, but I suspect updates to firewall rules on your VPN connection to your HCC instances will be required. I believe TLS will have to be enabled for the ODBC connection as well (HL7 Spy can support this). You'll also need to install the server-side class to support the fetching of HL7 messages (HICG_HL7.xml) to any interoperability namespace that you'll need access to from HL7 Spy. The HCC instances are pretty locked-down, so user role(s) may have to be adjusted for access to the required tables ... and that may require special dispensation from ISC.
go to post Jeffrey Drumm · Apr 20, 2023 EDIT: Hah, I guess you posted your solution as I was typing this ... and yeah, sort of what I thought it might be Are you calling (and testing) this from a DTL? If yes, have you looked through the DTL rules to see if the returned string's variable is being used as an argument to something like $system.Status.GetErrorText()? Does the same thing happen when you execute it from the IRIS prompt? Set tStrm=##class(%Stream.GlobalBinary).%New() Do tStrm.Write("SGVsbG8gV29ybGQh") Do tStrm.Rewind() Write ##class(<packagename>).DecodeBase64HL7ToFile(tStrm,"<ancillary>","</path/to/outputfile.ext>") Replace <packagename>, <ancillary>, and </path/to/outputfile.ext> with values appropriate for what you're testing, of course ...
go to post Jeffrey Drumm · Apr 19, 2023 ImageMagick is likely available for your platform and can be called using $ZF(-100). It has a LOT of image conversion options. A sample command line for svg to png conversion: $ convert -background none -density 1000 -resize 1000x myvector.svg myraster.png Example using $ZF(-100): Class User.Util.Image [ Abstract ] { ClassMethod Convert(pSourceFile As %String, pDestFile As %String, pDensity As %Integer = 1000, pResize As %String = "1000x", pBackground As %String = "none") As %Status { Set OsCmd = "/usr/bin/convert" Set OsArgs(1) = "-background" Set OsArgs(2) = pBackground // "none" for transparent and black for formats w/o alpha channel Set OsArgs(3) = "-density" Set OsArgs(4) = pDensity // set the vector width before resizing for best image quality Set OsArgs(5) = "-resize" Set OsArgs(6) = pResize // image output width/height (default is width 1000 keeping aspect ratio) Set OsArgs(7) = pSourceFile Set OsArgs(8) = pDestFile // file type controlled by extension; .png, .jpg, .gif etc. Set OsArgs = 8 Set tRC = $ZF(-100,"",OsCmd,.OsArgs) // On Linux, a return code of 0 indicates success If '(tRC = 0) { Return $$$ERROR(5001,"OsCmd "_OsCmd_" Returned Error Code ["_tRC_"]") } Return $$$OK } } Called like this: Set tSC = ##class(User.Util.Image).Convert("/path/to/filename.svg", "/path/to/filename.png")
go to post Jeffrey Drumm · Apr 18, 2023 Well, I learned something new too! I've always created classes in the Explorer pane and never realized that the Interoperability class types were templated out as file types. As someone who works primarily with Health Connect/IRIS for Health/HealthShare, that's pretty cool!
go to post Jeffrey Drumm · Apr 18, 2023 I don't think so. UpdateProduction (I think that's what you meant) is attempting to obtain state information for all of the business hosts and likely won't complete until they're all down. Calling it at the end should still be faster than having it enabled for each EnableConfigItem() call. The reality is that you appear to have a lot of processes that are dependent on polling rates and/or getting the appropriate responses back from external systems on notification they're terminating connections. If you need to shut down the interfaces fast, you really can only do it at the expense of graceful connection termination. Have you considered creating separate namespaces and compartmentalizing interfaces to keep your productions at a more manageable size? Business hosts in multiple smaller productions benefit from parallelism when performing administrative tasks like stopping/starting interfaces in bulk.
go to post Jeffrey Drumm · Apr 18, 2023 That should probably be a choice for completeness' sake. But you can create an ObjectScript class by right-clicking the server or one of its packages in the Explorer pane and entering the package/class name with a .cls extension. Use slashes rather than periods as package/class delimiters (if you use periods, it may display differently in Explorer until you refresh the window).
go to post Jeffrey Drumm · Apr 17, 2023 What's the use case for this function? ISC's Interoperability business rule editor has some quirks; it does not allow the passing of variables by reference to custom methods and that will cause objects to be passed as the OREF string in some cases. I was wondering if there was a way to work around that by obtaining another reference to the object by its OREF string, since that's what i ended up with. I haven't tried this yet ... it may not work for the specific scenario I encountered. But this discussion has certainly helped me understand how things work under the covers a bit better.
go to post Jeffrey Drumm · Apr 16, 2023 Hah! As always, you're THE MAN! Now, why isn't $ZOBJREF() in the documentation? I sure would have noticed that ...