Hi Evgeny,

Thank you for the suggestion.

We still then need to keep on developing primarily on Ensemble and once we release, then we create a release file for IRIS, which sounds good. This does create the risk of testing something on Ensemble and it maybe does not work on IRIS.

Every project has its own set of classes as well in addition to the shared code libraries. On these project specific classes, we may want to use new IRIS features. This creates the issue that I can't develop on Ensemble and only build and IRIS release. Not sure if you understand what I am getting at. The idea was that if a dev works on one of these projects, he/she only changes the server connection in Atelier, synchronise, compile and work. If that person needs to work on another project on Ensemble, the repeats the steps above. The git repo takes care of the source management, even though we are on different InterSystems products.

We use a local git repository on one of our servers.

To implement a pause prior to continuing the loop, use the hang statement.

The code provided above is perfect for all the other requirement. After the closing bracket of the "catch", add "hang 10" for a ten second "sleep".

You should also add a mechanism to stop this iteration somehow. It will be good practice.

ClassMethod Start()
{

  
    While (^RunMyApp = 1) {
        try {
            do ..YourMainMethod()
        } catch err {
            //log error here
        }
        hang 10
    }

If you then want to stop your code from running, open another terminal or use the Management Portal and set the global value:
set ^RunMyApp = 0

The repo contains an example. Here is an example of exporting the stack to a string in terminal

DEV>set sc = ##class(Examples.DebugStack).TestDebugStack()
Examples.DebugStack     TestDebugStack  Calling Method InnerStackTest with value: 5
|  |- Examples.DebugStack       TestInnterStack pVal argument: 5
|  |- Examples.DebugStack       TestInnterStack tMyVal: 15
|  |- Examples.DebugStack       TestInnterStack Calling TestThirdLevelStack with tMyVal: 15
|  |  |- Examples.DebugStack    TestThirdLevelStack     pVal argument: 15
|  |  |- Examples.DebugStack    TestThirdLevelStack     tFinalVal: 35
|  |- Examples.DebugStack       TestInnterStack TestThirdLevelStack completed OK
Examples.DebugStack     TestDebugStack  TestInnerStack completed OK
 
DEV>

It will be more readable if placed in a text file or a CSV. The "columns" are tab delimited.

It has the option of providing output to a string or a global character stream.

This is just an idea, and I may be corrected on this.
You get an array of artists. I can't find anything on storing arrays of the same key as you have in this scenario.

I would first do the web-service call.

  • Then create a DynamicObject using %FromJSON and the http response data as the source.
  • Get the array of artist from the DynamicObject using %Get("artists") on the DynamicObject instance.
  • Create an iterator on the object returned by the previous command using %GetIterator
  • Iterate through the collection - for each
    • Create a docdb entry and the properties or open an existing one. I recommend creating a separate method for this to keep the code concise.
    • Create a JSON stream of the current object on the iterator using %ToJSON(.tMyStream)
    • DO db.%FromJSON(.tMyStream)

I need to have the newlines in. The only reason why files are used, is because Cache does not support the RSA PSS padding required to sign the web-service messages I need to send. I then write what needs to be signed to a file and use opensl to sign it.

The value that needs to be signed is:
X-Date:CurrentDate\r\n
x-Client-Key:KeyValue\r\n
MessageBody

See: https://community.intersystems.com/post/sha256-signing-rsa-pss-padding

So it builds up the file to sign using the values and $char(13,10).
Then signs it using SHA256 and RSA PSS padding into a new file.
The contents of the new file is then base64 encoded.
The base64 encoded value is then sent together with the file contents, date and Client Key.

This works on Windows, hence the question about openssl and the newlines.

Is the base64 encoding a possivle culprit?

Thank you. I've also read up a bit and 8-bit contents will not be bothered by endianness.

You may have a point with the line endings. The value that is gettinhg encrypted has two \r\n in it - this works on Windows. I will try and change it to just \n for the Solaris server and see if that makes a difference.

Do you know if openssl uses the line-end to know up the where to sign and does it line by line, or does it include the line endings in the value that should be signed?

Apologies for all these questions. I am not very familiar with encryption, signing, openssl, etc.

I've created a config file from some random example and placed it in the bin directory. I can run it from there in the command prompt, but the $zf does not execute it.

Would you mind sharing your openssl config file and where it should reside? Which paths should be configured on Windows?

Will the user require the %CallOut service to be available to do this on a locked down install(production environment)

Thank you. The parameter of OnProcessInput being a %Stream.Object confused me, as that has no FileName property in the class reference. The FileName property did however work. I realize now that a FileCharacterStream object is passed to the OnProcessInput from the File InboundAdapter.

Regarding your question: I use the original file name in a Business Operation, which uses the File.OutboundAdapter. I concatenate a suffix to the original filename and then use putline of the OutboundAdapter to create the file.