Steve Pisani · Feb 10, 2022 go to post

Ah - ok that worked.

so..

- make sure IRIS TELNET Terminal (running on the Docker host) can resolve the HOSTNAME this container is running as (this was my actual issue !)
- in Container configure port range to use using Ens.Config if you want and if you do, expose ports in compose.yaml

thanks !
 

Steve Pisani · Feb 10, 2022 go to post

Hi Dmitry

Thanks for this.  I must be missing something from your post as I cannot get this to work.

In my IRIS Instance, in the interoperability configured namespace I have configured this:

set ^Ens.Config("FGTelnetRange","start")=63300
set ^Ens.Config("FGTelnetRange","end")=63499

In my docker-compose configuration I have exposed port 63300 as:   

...
- hostname: localhost
- ports:
    23:63300

and my docker host, (running the same operating system as my customer, which is, Windows),  is not running any other instance of IRIS or has open port 23.
Attempting to start a foreground window for a business operation, fires up IRIS telnet as expected, which, I'm guessing tries to establish a connect to IRIS in the container visible as port 23 as far as the host is concerned.  IRIS terminal , however, for me returns an error saying "TCP Connect() failed... No connection could be made because the target machine actively refused it."

From my host, firing up IRIS Terminal independently, and trying to make a connection to localhost:23 returns: 
<Session disconnected>

What seems to be happening (based on using other telnet clients too), is that the connection is made and then closed by IRIS.

Is this what you did ?

thanks - 

Steve

Steve Pisani · Feb 10, 2022 go to post

Thanks Eduard,  - I did come across that article before posting my question here - but I was hoping to find something that was less of a workaround/risk and more officially supported. 

@Dmitry Maslennikov approach - if I can get it to work, would be preferred as I could bake this into an image via configuration, and, it would require nothing other than just clicking the box in the UI.

Steve

Steve Pisani · Feb 7, 2022 go to post

Hi

For existing documentation, I believe others have already directed you. If, however, you are not doing an in-place migration (that is, you are installing on a new server), then one needs to get a bit more creative.  (There are several reason why you may choose to switch to new servers - for example wanting to move to a different OS, or a version that is supported by IRIS which you cannot simply upgrade to.)

Your InterSystems Sales Engineer or even the WRC, are able to provide the detailed advice you need which is often specific to your situation.  The main things to consider is the downtime you can afford when you failover to IRIS, and the architecture you have (do you have multiple Cache nodes, ECP, mirrors, etc ?).

In general however, what I have done successfully is create IRIS Asynchronous Mirror servers of the Cache nodes, then, (on switch over) shutdown Cache and promote the IRIS servers to active mirror failover members etc.  You obviously need to ensure that the IRIS set of servers is readily configured with security, memory etc to take over as a valid Async DR node.

Finally note that this creation of IRIS nodes as async mirror nodes to Cache servers is not supported as a production configuration but only allowed for migration.

Please reach out to InterSystems WRC or Sales Engineering for more in-depth discussion and planning.

Steve

Steve Pisani · Jan 30, 2022 go to post

Hi, 

In the above example, don't you have to instantiate ObjectScript.Embedded.Python ? Here you are calling instance method from instance method which work fine with 'self' (already knew that).. my question was asking about using/ referencing ClassMethods from other python class methods.

Steve Pisani · Dec 12, 2021 go to post

Hi.  In the real world, solutions are often made up of multiple namespaces, and code that exists in multiple databases where some databases are shared. For example nsA (running in namespace A) uses code from dbA, and dbLib. nsB uses code from dbB and also dbLib.

I would have thought that the GIT repository (or export folder) should have the option of being  built using the source Database of the component as part of the name in the path:eg:

/src/dbLib/cls...

/src/dbA/cls..

/src/dbB/cls...

On export, export logic resolves the true physical location of an item. 

Seperate Git Repositories per namespace is not the answer iether, as we don't want the dbLib code duplicated in multiple repositories.

@Timothy Leavitt 
​​​​​​Can you think of an enhancement, to this code that aligns export folder with actual dbname of exported item ? I would suggest perhaps the configuration global holding the export path, to allow for some sort of special string (eg "%sourceDB%") which is resolved at runtime.

Thoughts ?

Steve

Steve Pisani · Nov 20, 2021 go to post

Hi Tim, this is great, we spoke about this a while back and so glad you managed to get this out !!.  I've downloaded/installed it and will be using it for a project pretty soon.

Thanks again !

Steve Pisani · Oct 18, 2021 go to post

No reason at all. Just suggesting also that any custom methods can be invoked for all sorts of custom functionality - however sure, if that's all that is required... Go direct.

Steve Pisani · Oct 11, 2021 go to post

Hi,

That should work (as advertised) but if you want a workaround .... call a method instead, that implements the same thing:

...
    <Invoke Class="App.Installer" Method="SetAutoStartProduction"  CheckStatus="true" >
      <
Arg Value="${MyNamespace}" />
      <Arg Value="myProd.Production" />
    </Invoke>
....

- assuming 'MyNamespace' contains the namespace name you are setting up, as a variable (or hard code it).
Then include the method:

ClassMethod SetAutoStartProduction(myNamespace, prodClass) As %Status

   quit ##class(%EnsembleMgr).SetAutoStart(myNamespaceprodClass)
}

Steve

Steve Pisani · Jun 14, 2021 go to post

Hi Muhammad,

For FHIR capability, one would need to be running the healthcare version of IRIS - so, you would need to run, in your case the "IRIS for Health" product, which is also available as a Community Edition.

This feature does not require additional licensing in order to appear. You just need to be on the right version of IRIS for Health.

This option you mentioned here ("Health > FHIR Configuration > Server Configuration") was first introduced with release 2020.4, so, any version of IRIS for Health should be on this, or a later version to enjoy this feature.

InterSystem's AWS marketplace offering that launches IRIS for Health Community Edition,  here - does in fact launch this correct release. You could use that instance.

InterSystems' Quick Start tutorial here, which helps people learn about FHIR, also uses the correct release, and starts an instance for you in the cloud to use. If you are learning about FHIR  I suggest the Quick Start tutorial is your friend there too. 

You do not need to be an InterSystems customer to take advantage of this.

If you are a customer of InterSystems, you can download the version of IRIS for Health that was first released with this feature (2020.4) via the Distributions pages of the WRC, but note, that this was a Docker Container release only. 

Assuming you do not want to use Docker Containers, then, the next, non-container release with this feature is IRIS for Health 2021.1, and as soon as this is generally available, I would recommend to progress with that version.

Sincerely,

Steve

Steve Pisani · Apr 5, 2021 go to post

I have.

As Robert mentioned - disk I/O is one issue.  And the other issue is drive letter changes if the drive is moved between hosts (for example - the 'Journal File Location' pat set to D:\ in one instance - then drive 'D:' not found when the flash drive is moved between hosts.)  This can be overcome with scripts of sorts (potentially) - though I haven't tried to do that.

Steve Pisani · Nov 4, 2020 go to post

yes - I can't expect it was related to ZPM, but definitely seemed that way when it was the only image that didn't work in that state. 

Warning I guess for others reading this thread:  

docker system prune -f

Did remove 3 containers I had created, run and stopped on my system (but was planning to get back to them and start them again).  

thanks for now..

Steve Pisani · Nov 4, 2020 go to post

well that sucks.... 

docker system prune -f
Deleted Containers:
98a246148a9bbe5dd84ca435368dcc072173660320c7b3198788d135bb4a17bb
d53fcde88168b084928bda0a95daecfa08661efcdf5e04b875e75b9c45f373c1
54e4d30989a7b94a828d8e554acf6ad6caa9ca74928b28db011bfc30148cfe68
42f1432d7f62bbd0b6a9f8c4dc6e1e74fb9d6717c3c45b8a53d4228506cf4599

then re-running .. worked...

That may seem a great outcome to some, but, this un-predictability or, failure to report what the issue is (remember, the issue manifested in an IRIS process hanging), is not ideal. 
Also - I did try with non-ZPM containers successfully multiple times, whilst I was getting the issue, just to ensure, the issue was with only the zpm ones. It worked fine every time with non-ZPM containers.

Steve

Steve Pisani · Nov 4, 2020 go to post

Hi - 

Note that using the ZPM images to build a HealthShare Foundation namespace (interoperability enabled database and namespace), using the HealthShare -> Installer wizard -> Configure Foundation ; .

OR you can try this, using this line:

ZN "HSLIB"
DO ##class(HS.HC.Util.Installer).InstallFoundation("MYNAMESPACE")

will hang mid-way.

However,  above operations complete successfully using the standard, non-ZPM enhanced builds.
I haven't tested any other functionality.

Steve

Steve Pisani · Oct 18, 2020 go to post

Hi - note that in order for this WHILE loop to iterate over the tXMLList (which was your XML string converted to a $LIST string) you need to also initialise the variable ptr = 0 outside the loop.

Also note this code only iterates over the source string and retrieves each value. - if you want to to replace your 'a' string as per your original post, use Robert's solution, or build this out in a new variable.   like this:

Set tXMLList = $LISTFROMSTRING(a, "</RollNo>")
Set ptr=0,newA=""
while $LISTNEXT(tXMLList,ptr,value) {
    Set $P(value,">",*) = "***"
    Set newA=newA_value_"</RollNo>"
}
Set a=newA

A warning on both solutions offered so far is that XML elements are not case-sensitive, so beware when the element "RollNo" is not provided to you in exactly that mix of lower/uppercase.

Steve Pisani · Jul 15, 2020 go to post

Hi Nigel

Ok yes - that would work. When the context object is being populated with individual property values, - if the last thing I do is:

set myContextObject.context=myContextObject

then I can pass in the property 'context' into my function to gain access to the whole object. 

I could also just pass the rowID of myContextObject, and have myFunction re-instantiate it too.

I think this will have to be what I do, if the entire context object is not made public to my function.

Thanks - Steve

Steve Pisani · Jul 15, 2020 go to post

Hi Nigel.  

Not really. What I want to do is, in my Business Rule, call my custom function, passing the entire context object, not individual properties. Putting it out there again:

Assume I have a custom function called 'ValidateAllMandatoryFields' that returns a 1/0 from checking multiple properties of the context object and their inter-dependancies.

I'd like my rule to simply say:      IF ValidateAllMandatoryFields(<something>) ...
and for the function to see the whole context object, and do what it wants.

I don't want my rule to have to say:  IF ValidateAllMandatoryFields(context.Properties.PropA, context.Properties.PropB, etc.etc...)

Steve

Steve Pisani · Jul 12, 2020 go to post

Hi Fernando,

Strange. I've never seen this before, and it seems like a bug to me.  If no other suggestions appears here, I would reach out to the support team at InterSystems for advice.

If just defining classes and routines, VS Code is another alternative IDE. This is being developed further to bring it in line with the features of Atelier and provides another formidable option.

Of course the more mature IDE is IRIS Studio, another alternative for you, if running on a Windows client.

 Steve

Steve Pisani · Mar 11, 2020 go to post

Hi Wayne,

I'm not sure I can help you with an article, but for what it's worth, the error indicates there may be an issue with Soap security policies of the service. 

For example, where the mock service is expecting to be called using HTTPS, but it is not. 

To try and resolve, it may be worth reviewing what the mock service is expecting security-wise, and match that with how its being invoked.

Steve

Steve Pisani · May 27, 2019 go to post

Hi,

Can you also post a screenshot of your Web Application setup on the IRIS server that defines the rest endpoint ?

Thanks-  Steve

Steve Pisani · May 2, 2019 go to post

Hi,

In reading this - I'm wondering - what is the real advantage of #2 ?   

- Steve

Steve Pisani · Mar 6, 2019 go to post

Hi,

My guess is you are calling the query with more arguments than it expects on those times that it is failing..

Providing or inspecting again  the code making the call from the client side, would be a good start to fixing your issue. 

Steve

Steve Pisani · Nov 26, 2018 go to post

Hi Evgeny,

Any new on when the Community Edition of IRIS will be available ?

Steve

Steve Pisani · Nov 21, 2018 go to post

Hi,

No sooner have I asked the question, then I found the solution myself !.

and that is,  when added to a Production, the EnsLib.MsgRouter.RoutingEngine class that executes the rule has a production settings "Force Sync Send", to force all SENDS to be Synchronous.

Steve

Steve Pisani · Nov 6, 2018 go to post

Hi Chris,

I agree - note the Schedular basically STARTS or STOPS a business host automatically, on a pre-defined schedule -  (so it applies to Operations and Processes too, not just Services, which are the items that have a CallInterval feature).

For regular invocations of work on services,  in almost all cases,  absolutely - CallInterval is the way to go, and is what is used mostly. I certainly would prefer looking at the production and status of my business hosts and see all of them 'green' and running - even though, running might actually means 'idle in between call intervals' .  Using the Schedular the stopped business host will appear 'gray' when it is not started (ie, it is disabled) 

There are valid use cases -  though, a Schedule on, say, a Business Operation makes sense. For example, you may want to send out messages to business operation that interacts with a fee-per-transaction end point that is cheaper during certain times of the day. In this case, you can disable the operation, send queue it messages all day (which will accumulate in it's queue), then, at the appropriate time, enable the business operation via the schedular, then, disable it again after a period of choice.

In this thread's case, the easiest approach is to use OnInit to prepare the data and send the data. OnProcessInput (called by the interval, which can be very long), would do nothing but quit. That would work. Of course there are other approaches.

I wanted to include the Schedular information as it is often overlooked, and, sometimes, the full story and use case of the original poster might not be evident, and, schedular might have been appropriate. 

Thanks for your feedback.

Steve

Steve Pisani · Nov 6, 2018 go to post

Hi Eric

If you want your service t0 be part of the framework, but not actually use any specific connection functionality typically offered by adapters (SQL, FILE, ..etc)  Just ensure that the adapter is first set to  'Ens.InboundAdapter':

Parameter ADAPTER ="Ens.InboundAdapter" ;

And - set your PoolSize is set to 1, so a job is started. with the production.  Note that for every cycle of the Call Interval setting, the OnProcessInput method will be called.

If you want to regularly do your work (ie:  "go through a list of values in a global and compare dates. If criteria is met, it will send an email."),  then, do this in the OnProcessInput method at your desired CallInterval.

However - As you said "on start..." I'm assuming you meant, on start of the production as a whole -   In this case, leave the OnProcessInput method empty with just a 

Quit $$$OK

statement, and, (as others mentioned here), put the logic in the OnInit() method of your service, which will be invoked on production startup or enabling/disabling of the service.

Note that without the Adapter parameter setting above, and the pool size set to 1 - neither OnInit, nor OnProcessInput are called.

Now - Productions are meant to keep on running. You may eventually move away from putting this logic in the OnInit code or somewhere which requires a Production re-start in order to execute, as this effects other running business hosts ....  To explore other options further you can

(a) Work with the CallInterval which calls OnProcessInput after n seconds, and build in logic that determines if a particular cycle should just do nothing, or (say, on the change of the day, or other controlling factors, like, the size of your global entries) - would go ahead and do the emails.  Note that you can set Properties for your business service, to record state - which you can initialise  a value for in the OnInit, and update regularly during the running state of the service if you need to.

(b) Look at the Schedular feature.  The Schedular feature controls the running state of a business host. With the schedular you can elect to Enable/Disable any service on a pre-defined schedule. So - You can enable  your service, (with OnInit code to check globals and send emails), at an interval of choice without needing to stop/start the production. click : here for documentation.

Sincerely -

Steve