go to post Enrico Parisi · Jun 4 I assume that your interoperability is using Application ACK, so the response ACK in traced (there is an Ens.MessageHeader and HL7 Message reponse with ACK). select req.TargetConfigName as BusinessOperation, DATEDIFF('ms',req.TimeCreated, res.TimeCreated) as ResponseTime from %PARALLEL Ens.MessageHeader req, Ens.MessageHeader res where req.SessionId=res.SessionId and req.TargetConfigName = ? and %internal(res.SourceBusinessType)=3 and %internal(req.TargetBusinessType)=3 and req.TimeCreated between ? and ? First placeholder/parameter (?) is the BO name. To narrow the scope (and runtime) you can use the second and third placeholder/parameter to limit the date/time range. Note that the returned ResponseTime will include the time the request remains in queue (if any). If you have many messages, %PARALLEL will help to speed up.
go to post Enrico Parisi · Jun 4 My BIO can be found in my DC profile, so I just copy/pasted it from there. I invite everyone who posted here to add/copy this info in their profile 😀 The first two systems I worked with using InterSystems technology were a PDP-11 running M11+ and a VAX 11/750 running M/VX. Too many years ago to count! 😊Since then I've used most, if not all, InterSystems products up to IRIS and HealthShare today.I'm Italian living in Switzerland and I work as Senior Consultant at GAIVOTA consultin SA, we provide professional services for InterSystems and other technologies.Fun Fact: apart from DC, I don't have ANY social account! 😁Hobbies: technology and, when I can, I like diving (PADI Advanced) in nice tropical seasLinkedin: see Fun Fact 😂 I've attended most of the InterSystems conferences in the last decades and I'll be in Orlando @ READY 2025.
go to post Enrico Parisi · Jun 3 If the "internal HTTP" is using the PWS (Private Web Server), then NO, NIET, it's a bad, very bad idea. DO NOT USE THE PWS for anything apart testing and local PC playing. For ANYTHING serious, install and use a "real" web server (Apache, NGINX or IIS). It has been so since EVER and has been documented since ever, but it seems that many people still used the PWS. I guess that was (one of?) the reason that drove InterSystems to completely remove PWS since.....2024.1? (or was 2?). From Ensemble 2018..3 documentation (the oldest available online): Note:When installing Caché and Ensemble, this private version of Apache is installed to ensure that: The Management Portal runs out of the box. An out-of-the-box testing capability is provided for development environments. The private Apache web server is not supported for any other purpose. For deployments of http-based applications, including CSP, Zen, and SOAP over http or https, you should not use the private web server for any application other than the Management Portal; instead, you must install and deploy one of the supported web servers (for information, see the section “Supported Web Servers” in the online InterSystems Supported PlatformsOpens in a new tab document for this release). Additional info: Discontinue Apache web server installations - FAQ Effective with the first EM release in 2026, the private web server will be discontinued; at that point, upgrades of existing InterSystems IRIS instances will remove the private web server.
go to post Enrico Parisi · Jun 3 Using Process Private Global: ClassMethod setLayout(layout) As %Status { MERGE ^||layout = layout Set node="^||layout" For { Set node=$query(@node) Q:node="" Write node,"=",@node,! } Quit $$$OK } Using local variable array: ClassMethod arrayQuery(myArrayLocalName) [ PublicList = myArrayLocalName ] { Set node="myArrayLocalName" For { Set node=$query(@node) Q:node="" Write node,"=",@node,! } } Note: the idea of using Process Private Global was INSTEAD of local variable array all around, not merging etc.
go to post Enrico Parisi · Jun 2 Sorry, my bad, a typo, please replace IsObject with $IsObject If '$IsObject(..Adapter.%Client.HttpRequest) {
go to post Enrico Parisi · Jun 2 Another option, in your BO add: Property LocalInterface As %String(MAXLEN = 255); Parameter SETTINGS = "LocalInterface:Connection:selector?context={Ens.ContextSearch/TCPLocalInterfaces}"; Then before calling the service (..Adaper.Invoke*()) add this: If 'IsObject(..Adapter.%Client.HttpRequest) { Set ..Adapter.%Client.HttpRequest=##class(%Net.HttpRequest).%New() } Set ..Adapter.%Client.HttpRequest.LocalInterface=$ZStrip($P(..LocalInterface,"("),"*W") Edit to add: Why are you extending EnsLib.SOAP.GenericOperation? For a SOAP BO using EnsLib.SOAP.OutboundAdapter the class signature is supposed to be: Class osuwmc.Nutrition.OSU.CBOARDNetMenuOperation.CBORDHL7Port Extends Ens.BusinessOperation
go to post Enrico Parisi · Jun 2 That won't work, you are just setting a %Net.HttpRequest object in a (private) variable called HttpRequest that is destroyed when the method ends. You need to set/change the %Net.HttpRequest instance contained in the ..%Client property of the adapted AFTER the web service client class is set/instantiated in ..%Client. Did you had a chance to test the modified adapter I've posted? Maybe tomorrow I'll have time to test it.
go to post Enrico Parisi · Jun 2 You can extend EnsLib.SOAP.OutboundAdapter and add support for LocalInterface and use the "new" adapter in your BO. With "inspiration" 😁 from EnsLib.HTTP.OutboundAdapter, something like: Class Community.adapter.SoapOutbound Extends EnsLib.SOAP.OutboundAdapter { /// In a multi-homed system, specify which network interface the TCP connection should go through. An empty value means to use any interface. <br/> /// To be able to bind to IPv6 interfaces you may need to enable IPv6 in your instance. This is done in the System Management Portal under /// System Administration > Configuration > Additional Settings > Startup, by editing the IPv6 setting. Property LocalInterface As %String(MAXLEN = 250); Parameter SETTINGS = "LocalInterface:Connection:selector?context={Ens.ContextSearch/TCPLocalInterfaces}"; Method OnInit() As %Status { Set ..%Client.HttpRequest=##class(%Net.HttpRequest).%New() Set ..%Client.HttpRequest.LocalInterface=$ZStrip($P(..LocalInterface,"("),"*W") Return ##super() } } I did not tested it, try it and let us know. Nete, if for any reason you reinstantiate ..%Client.HttpRequest, then you need to set the LocalInterface property. Having LocalInterface support in EnsLib.SOAP.OutboundAdapter "out of the box" can be worth an entry in the ideas portal.
go to post Enrico Parisi · Jun 2 $query argument can be a global or a public variable, so when using local variable array change the method signature: ClassMethod test(array) [ public= array ] Or use a temp global or, even better, a Process Private Global instead.
go to post Enrico Parisi · May 29 In the...good old days, we used to do that in one line 😂 s node="array" f s node=$q(@node) q:node="" w node,"=",@node,! array(1)=1array(1,1)=1,1array(1,1,1)=1,1,1array(1,1,1,1)=1,1,1,1array(1,1,2)=1,1,2array(1,1,3)=1,1,3array(2)=2array(2,1)=2,1array(2,1,1)=2,1,1
go to post Enrico Parisi · May 28 If I recall correctly I had a similar issue in some old Ensemble system but I'm not 100% sure the global was really that. If you can stop the production, then I think it's safe to kill ^Ens.AppData, with the production running I don't think killing it it's a good idea. A curiosity, do you use EnsLib.SQL.Snapshot class in some SQL host (BO)?Is the content of ^Ens.AppData somewhat related to EnsLib.SQL.Snapshot?Looking at the content of ^Ens.AppData, what type of adapter/operation is likely using it?
go to post Enrico Parisi · May 27 When I was migrating a system I had to export and import SQL Gateway Connection, so in the source system I exported to a tab delimited file and in the target system I imported the definitions. The code to create the imported definition is: Set SQLConnection=##class(%SQLConnection).%New() Set SQLConnection.DSN=$p(line,tab,1) Set SQLConnection.Name=$p(line,tab,2) Set SQLConnection.ReverseOJ=$p(line,tab,3) Set SQLConnection.URL=$p(line,tab,4) Set SQLConnection.Usr=$p(line,tab,5) Set SQLConnection.bUnicodeStream=$p(line,tab,6) Set SQLConnection.classpath=$p(line,tab,7) Set SQLConnection.driver=$p(line,tab,8) Set SQLConnection.isJDBC=$p(line,tab,9) Set SQLConnection.needlongdatalen=$p(line,tab,10) Set SQLConnection.noconcat=$p(line,tab,11) Set SQLConnection.nodefq=$p(line,tab,12) Set SQLConnection.nofnconv=$p(line,tab,13) Set SQLConnection.nvl=$p(line,tab,14) Set SQLConnection.properties=$p(line,tab,15) Set SQLConnection.pwd=$p(line,tab,16) Set SQLConnection.useCAST=$p(line,tab,17) Set SQLConnection.useCASTCHAR=$p(line,tab,18) Set SQLConnection.useCOALESCE=$p(line,tab,19) Set SQLConnection.xadriver=$p(line,tab,20) Set sc=SQLConnection.%Save()
go to post Enrico Parisi · May 25 If you want/need your code to handle ANY situation (JSON size), then you should use the first option. Let's try with the second option: USER>Set Body={}.%FromJSONFile("c:\temp\BigSample.json") USER>Set Request = ##class(%Net.HttpRequest).%New() USER>Set Request.Server = "server" USER>Set Request.Location = "location" USER>Set Request.ContentType = "application/json" USER>Do Request.EntityBody.Write(Body.%ToJSON()) DO Request.EntityBody.Write(Body.%ToJSON()) ^ <STRINGSTACK> USER> As you see, it does not work. Now the first option: SER>Set Body={}.%FromJSONFile("c:\temp\BigSample.json") USER>Set Request = ##class(%Net.HttpRequest).%New() USER>Set Request.Server = "server" USER>Set Request.Location = "location" USER>Set Request.ContentType = "application/json" USER>Do Body.%ToJSON(Request.EntityBody) USER>Write Request.EntityBody.Size 18378462 USER>Write ##class(%File).%New("c:\temp\BigSample.json").Size 50273869 USER> Curiosity: the difference between the original json file size and stream loaded into Request.EntityBody stream is due to the fact that the file is formatted with indents while the json exported stream is "compact" (minified) with no indents and new lines.
go to post Enrico Parisi · May 24 This is new info, you did not mention this in your original question. Can you provide some context on your implementation? Would you mind to share the code you are using to save "data inside response.Data"? What class is "response"?
go to post Enrico Parisi · May 23 From the example in the first post it seems the stream is not a property of an Ens.Message, that's why is not purged.
go to post Enrico Parisi · May 22 You explicitly saved the stream using CopyFromAndSave(), so it will persist (on disk) until it's deleted. It's like saving a persistent class, it persist even when the code has finished executing. Fortunately! ☺ What's the point of saving a stream that you don't want to persist?
go to post Enrico Parisi · May 21 But...are you using a Business Operation with EnsLib.SOAP.OutboundAdapter?
go to post Enrico Parisi · May 21 What namespace are you logged when you try to create that routine? Maybe in your namespace the %Test (or %Test*, or...) is mapped to a read only database? Otherwise you think you are authenticated as superuser but in fact you are not.
go to post Enrico Parisi · May 21 In your generated (from wsdl) SOAP client class change the LOCATION class parameter with correct url including port number. Another option is to set the Location property in your code when you use the client class, somthing like: Set wsClient=##class(your.generated.SoapClient).%New()Set wsClient.Location="https://path.to.server:NNNN/path.to.service"Set client.SSLConfiguration ="SSLConfig"
go to post Enrico Parisi · May 20 It looks like there is some disk I/O difference between the two systems. How does the two systems storage (disk, controller etc.) compares? Are the 2 systems equally configured in terms available RAM and of global buffers? Is the shared memory using large pages? (check messages.log during startup) I'd monitor and compare disk usage and I/O while running.