Hi

You can run the method in the 'Output' window which you can access from the 'View' menu.

Just a note on the difference between Cache Classes and Classes in other OO based languages. 

Cache supports two types of method:

Method ABC(Param1, param2, ... paramN)

and

ClassMethod XYZ(param1, param2, ... ParamN)

a Method acts on a instance of your class whereas a class method is independent of the object instance. i.e. you do not need to create a new instance or open an existing instance of a class in order to invoke a class method.

The second thing is that there a developer hooks that allow you to run code based on the following actions:

%New(): If you write a method %OnNew() this method will be run after the %New() method has been run. It allows you to do any initiation logic on the new instance that has been created.

%OnOpen(): This method is called after the instance of the class has been opened.

%Save(): There are two methods %OnBeforeSave and %OnAfterSave() that you can write that are called before or after the %Save() method.

%Delete: Likewise has two methods %OnBeforeDelete () and %OnAfterDelete() where you can write code that is executed before or after the %Delete() Method.

We don't really have the concept of a "Main" method that is automatically invoked when you reference the class other than through the %OnNew() and %OnOpen() methods.

In Ensemble things are slightly different in that Business Service/Business Process and Business Operation classes have methods such as OnProcessInput(), OnProcess() and in the case of Business Operations there is an XDATA block where you can specify the method to be invoked based on the message type being processed by the Business Operation.  You could consider these methods as the 'Main' methods of the class but in reality they are the methods where the developer is expected to put the application logic for the class. There are other methods that the Ensemble Production will execute before it is ready to run your code and there are methods that the Ensemble Production will run after your methods have completed.

Cache/Ensemble/IRIS also support the ability to write application/system specific code that will be executed when Cache Starts Up or Shuts Down and likewise when an Ensemble Production Starts Up or Shuts Down.

Have a look at the documentation on %ZSTART for more information on what you can do when Cache starts up or shuts down. There is similar documentation in relation to Ensemble Productions.

Nigel

Hi

In which time zone are the times for the presentations? If I am in South Africa which is GMT+2 in GMT terms what are the times for these presentations?

Is the seminar being held in Germany in which case I can probably work it out via google but it's not clear other than the announcement says that the presentations will be available in English and German. Hence my assumption that its being held in Germany.

Thanks

Nigel 

Hi

On your Business Service Settings tab under the 'Additional Settings' tab there is a an option "NACK Error Code" whose definition reads as:

Controls the error code in MSA:1 of the NACK message this service generates when there is an error processing the incoming message. The default 'ContentE' behavior is to return code 'E' for errors with the message content, and code 'R' for system errors encountered within Ensemble while attempting to process the message. This distinction is important because system errors are expected to be solved so that if the remote client tries again at a later time they may not occur, while message content & validation errors are expected to require correction at the source and not to be worth retrying in the same form. However some client systems may expect or require a different error behavior. Therefore 3 additional behaviors are offered. The 4 behaviors are as follows:

  • ContentE = Use MSA error code 'E' to report errors in message content and code 'R' to reject due to (retryable) system errors.
  • ContentR = Return 'R' for content errors, 'E' for system errors.
  • AllE = Return 'E' for all content and system errors.
  • AllR = Return 'R' for all content and system errors.

Earlier versions of Ensemble used the behavior 'ContentR' exclusively.

As the documentation points out earlier versions of HL7 supported AA and AE, later versions added supports for CA, CE and CR.

The other attribute is "Use ACK Commit codes" and the documentation reads:

If 'true' and the HL7 message VersionID is 2.3 or higher, use the 'enhanced-mode' ACK 'Commit' codes ('Cx') in MSA:1 ('AcknowledgmentCode'). (Otherwise use the legacy-mode 'Ax' codes.) 

So to get the AA, AE and AR codes you need to make sure that the "Use ACK Commit Codes" is unchecked (false) and then from the "NACK Error Code" select "ContentE"

Yours

Nigel

To add to Vic's response I suspect that the access violation is not necessarily about the sql access rights to the event tables but rather the access rights to the UI component that displays the event log and the access rights to access the database using SQL. I suspect that you need to assign an appropriate role(s) that will give the user access to the UI component and the ability to run sql. You can test this last aspect by using the Management Portal - System Explorer -> SQL and attempt to execute a simple query "select * from {table}" where {table} is the event table you want to access. I don't have access to HS 2018.1 at the time of writing this response.

Th answer of course will lie in the documentation as suggested by Vic. The trick is to ensure that the user has enough priviledge to do what they need to do but do not have so much access that they could potentially get to areas of the Management Portal and data that they should not have access too. It can be a bit tricky to get it perfect. If you have many users who need this specific access and it turns out that you require a combination of certain roles, tables etc then create a generic user with those assigned attributes and then when creating new users use the "Copy From" option on the "Create New User" page and specify the generic user you have created.

Nigel

Hi

The reason that you are getting these errors is that there is a mismatch between the following attributes of the Client and Server Adaptors. Jeffrey mentions Framing which is essentially how Ensemble detects the beginning and end of each HL7 message. Within the message itself though your message consists of 1 or more Segments. In order to determine the end of a segment Ensemble needs to know what terminator to expect which can be <LF> or <CR,LF>. In order to detect these characters Ensemble needs to know what character set the 3rd Party Adapter is using. So you need to confirm that the attributes CHARSET (Character Set) and ENCODING. The default values for these should be 'Latin-1' and 'UTF-8'. On the subject of Framing your choice is dependent of whether you are the HL7 TCP Inbound Adapter (in a Business Service) or you are the HL7 TCP Outbound Adapter. If you are the server then you have the choice of ensuring that your Framing matches the 3rd Party Client Framing. However you also have the choice of Flexible which essentially tells the Ensemble Adapter to interpret the characters being streamed to the Server and based on Pattern matching rules Ensemble can 'auto-detect' the framing. However when you are working with the Ensemble HL7 TCP Outbound Adapter you don't have the option of 'Flexible' and you either need to confirm that you and the 3rd Party are using compatible Framing formats and you can find out if they support Flexible then you can set the value for your  Client Adapter Framing to a value of your choice 

Nigel

The best way of doing this is to create a class with a single property 'property Data as %BinaryStream'

class MyData extends %Persistent

{

property Data as %BinaryStream;

}

Then, I assume you you have a class that inherits from %CSP.REST (assume it is called MyRestClass) and in the XDATA Routes block define a route definition

<Route Url="/myapp" Method="POST" Call="SaveData" />

where /myapp is a Web Application defined in Management Portal -> System Administration -> Security -> Applications -> Web Applications. When you define the application specify the application URL ("/myapp"), the namespace where your data is going to be saved, and in the field "Dispatch Class" specify  "MyRestClass" and then Save the Web Application Definition.

in your REST Class(MyRestClass) define a class method

classmethod SaveData() as %Status

{

    set tSC=$$$OK

    try {

        set obj=##class(MyData).%New()

        set tSC=obj.Data.CopyFrom(%request.Content) if 'tSC quit

        set tSC=obj.%Save() if 'tSC quit

    }

    catch ex {set tSC=ex.AsStatus()} 

    quit tSC

}

This is just one approach. As Robert suggests below there are a number of ways of manipulation images in CSP but my example is one that I have used before

Hi Olga

Does this challenge apply to people who live outside of the USA?

I would happily write a review but I would also like the $25 prize unless the prize could be converted into Global Master points which I could then redeem for the current items in the Rewards list.

By the way, when I had accumulated enough points to redeem some of them for one of the prizes I set my heart on the InterSystems Back Pack but by the time I tried to redeem my points the back packs had all gone and so I settled on the JBL speaker (which I absolutely love. It's very good and looks great), a pair of socks and some funny attachment for my phone which I am still trying to work out how it works.

Is there any possibility that you will be getting more InterSystems Backpacks and if so please will you put my name on one and let me know so that I can send in my application to redeem some points for the back pack.

I don't suppose that ISC marketing have any back packs hidden in their Marketing offices that you could possibly bribe Maureen to let you have one for me? :-)

Yours

Nigel

Hi

In one of my Zen applications I built a custom Login Screen and in the Web Application Definition I call that login csp page. In my case I maintain my own User/Role tables and when I add or modify a User I use the Ensemble security method calls to create or update the user in Ensemble.

The Zen Custom Login forms are designed to validate the user against the Ensemble Users Table.

Given that in your login page the User and Password fields can be accessed through the DOM model you can get the values from those fields by specifying a "OnChange" or equivalent JS event and you can then get the value entered by the user and you can then write those values into your own "Login Audit Table". Likewise you can detect when the Zen session has closed and so you could trap that and update your "Login Audit Table" to indicate when the user logged out.

In the Zen documentation they give an example of a simple custom login form:

<page xmlns="http://www.intersystems.com/zen" title="">
  <loginForm id="loginForm" >
    <text name="CacheUserName" label="User:" />
    <password name="CachePassword" label="Password:" />
    <submit caption="Login" />
  </loginForm>
</page>

So you could trap the user name and password values (the password value will have been encrypted so if you needed to see the actual password value you would have to unencrypt it).

The only problem I foresee is that once you have submitted the form you won't know if the user has logged in successfully until your Home page displays so you would have to store those values in a temp global and then if you get to your Home screen you would know that they had logged in successfully and you could create your login Audit. 

Given the way that the Cache/Ensemble/IRIS documentation is structured you may well find a section elsewhere in the Zen documentation that might tell you how to trap the outcome of the 'submit' but I have not attempted to see if my theory returns any more useful information.

Nigel

I wrote my first reply in rather a rush. What would help me is to understand how you came to the world of InterSystems and where it fits in your future development plans.

What I can say is that it is one of the most consistent environments in which to develop applications. Once you have understood the basics of the Language, the concepts of Classes and Tables, the common approach to the multitude of adapters supported for Interoperability you will find that no matter what you want to do within the technology you will find that everything is built upon a very simple yet powerful paradigm. Keep It Simple, There is no fluff in IRIS. There are no masses of libraries that have to be included and compiled into each component of you application. Object Orientation (of which I am a dedicated advocate) is so powerful that once you have written some core classes and methods and you wrapper them in such a way that they can be seen as Java Methods or Relational Stored Procedures just be adding a couple of key words and possibly running them through a wizard that will create the project wrapper to expose them as such to the outside world you will come to realise that the symbiosis of data and logic is unlike anything you will have experienced in other technologies.

If you give me a relatively experienced developer with a passion for developing software I can train that developer within 2 weeks to become a IRIS developer capable of creating classes (and implicitly tables), teach them when to use SQL rather than OO, create a basic Production that consumes data from an external source, manipulate and transform that data and either store it within IRIS or send it on to some other 3rd party application. Give me another 2 weeks spread over 2 months and I will help that developer tackle specific issues relating to any project that you start developing in IRIS. So give it some thought and let me know how best I can get you up and running in these probably the most innovative and enjoyable technologies on the market today.

Hi

I have written about 20 Integration Productions over the last 10 years and have worked for and with InterSystems for nearly 30 years. The InterSystems documentation is very good however it takes a certain amount of experience to get the most out of the documentation.

What I would suggest is that you look in the SAMPLES namespace as there are a number of example productions and other features of Ensemble and IRIS.

If you are working in the Cache Studio then use the "Project" -> "Add Item" to add all of the examples into your workspace.

The second thing I would advise is that you take a look at Microsoft V S Code which has a Cache ObjectScript Extension as well as a few others such as a Lint extension, multiple connections and so on. The advantage of working with VS Code is that it is quite possible that you will be working with other technologies such as Web Technologies like Angular and Python. VS Code also integrates with GIT (Git For Windows, Tortoise)

I have to confess that I am definitely more at home in a Windows Environment than I am in Linux and I am waiting for a Hard Drive upgrade to my laptop in order to install and work with Containers and there is of course a lot of emphasis on Linux/Unix and Containers in everything you read in the documentation and of course in the product distribution kits but once you have your O/S in place, your Containers, Your Cloud Environment then the first thing you'll notice that once installed Cache, Ensemble and IRIS look and behave identically on all of these platforms and technologies. So anything I say about memory management or Interoperability Adapters or coding standards is true across all platforms.

You happen to have asked a question that I am very passionate about. From getting the most out of Cache Objectscript, Coding Standards, Designing your database Classes/Tables. How to get the most out of Cache Objects, Cache SQL and Cache Direct. How does InterSystems implement Object Orientation as well as Relational SQL without having to duplicate, replicate or manipulate the underlying data in order to provide a seamless integration between the two. How to access the database directly bypassing OO and SQL: Why would I want to do this? What are the benefits? what are the pitfalls?

Then there is the whole topic of designing great Integration Productions. There are many concepts to consider here:

1) How is data getting into your production. How to design and configure your inbound and outbound adapters.

1.1) How to transform data using the powerful string manipulation functions that are intrinsically at the heart of Cache.

2) How to create Request and Response Messages to send salient information from your Business Services to Business Processes and/or Business Operations (Pushing data out of the Production, interacting with external third party applications and/or databases), Interacting with .Net and Java.

3) Build your UI: What are your options? Cache Server Pages, ZEN, Bootstrap, Angular, Python?

4) Synchronous vs Asynchronous Calls

5) BPL: Pro's and Con's

6) Data Transformations (DTL's)

7) HL7 and FHIR (I am deeply involved in FHIR at the moment) and other standards DICOM, LDAP, CDA, CCDA, HTTP, SOAP/Web Services, Java, .Net, TCP, ASTM, JSON, XML and the 43 other variations thereof

8) Reusability of code

9) Debug Logging

10) House Keeping

11) Alerting, What does IRIS offer in the way of creating Alerts and monitoring of those Alerts, assigning alert issues to specific Users. Alternatively making use of a custom Alerting system (I have one of those which I am willing to share)

12) How to configure your servers. Disk allocation, memory allocation, process memory

13) Understanding how IRIS manages data: Retrieving data from disk, managing that data in memory, what happens when data is modified in memory? Do other users see that modified data in memory? When that page of data in memory needs to be written back to the disk system: how does that happen? What happens if the server crashes in the middle of that physical update to disk? How does it recover

14) Why is IRIS so fast? How are Globals (The underlying physical storage structures that are projects through Object Classes or Relational Tables) structured

14.1) Indexing: Conventional Indexing, Bitmap and BitSlice Indexing, iFind Indexing. What are the differences? When to use them, the power of iFind Indexing on unstructured but important data such as Names and Addresses

15) How do I optimise the I/O of data from your disk system. Databases, Journalling, Write Image Journaling, Archive databases

16) Security: Auditing, Access Control, Encryption

17) InterSystems Learning Services

18) The Developer Community

19) InterSystems Open Exchange

So, as you may have gathered I could write anything from 1 page to an entire chapter based on my personal experience on every one of these topics so let me know which topics are most critical to you and I will do my best to answer each of them - documentation and in some cases code examples.

One of the tricks is absolutely the issue of standards, naming conventions, templates for classes, methods, property definitions, foreign keys, the difference between how IRIS manages Objects vs. Relational Tables. What are the implications when you want to write functions that can be called by both paradigms. For example, using the %OnNew, %OnBeforSave, %OnAfterSave vs SQL Insert, Update and Delete Triggers.

Methods and Class Queries projected as Stored procedures that can be invoked by external relational environments yet behave as Object functions within IRIS

What would help is if you could give me some idea about your background? What technologies have you worked with before you finally reached "The One True Database and Development Technology for Dedicated, Enthusiastic and Passionate System Architects and Developers" laugh 

Is your experience primarily in the Relational world of Microsoft and Oracle, Java, Web Development and so on. Knowing this will help me draw parallels between what you already know and how best to bridge the gap into Ensemble and IRIS.?

Looking forward to hearing from you

Nigel Salm

and to add to my collegues....

You can create Ensemble productions where Business Services create request messages and send the Asynchronously to one or more Business Processes. If the Pool size on those Business Processes then you will end up with multiple Business Processes Instances simultaneously  processing the request messages in the queue for that Business Process. Likewise, Business Services can have a pool size > 0 and the same paradigm works. Ensemble will evaluate the number of messages in the queue for that Service and if need be it will add more instances of the service to process the queue. The only thing you need to worry about is that when  message is picked up by a service of queue it should be locked so that another instance of the serviv=ce or process won't pick up the same same message.

Apart from that Cache has been optimised over the last 20 years to offer the best transactional processing power of any mainstream database and concepts such as threading in other technologies require extra work by developers to implement whereas in Cache you can take it for granted that all of that low level stuff is intrinsically taken care of for you by the Cache Kernel