Hi Tom,

For much of what you requested, you should look at InterSystems IRIS's new Document database model.

The Document databases accepts and persists collections of JSON Documents inside of Cache . Additionally, it allows you to define a set of properties for documents in this document databse.  These properties correspond to elements in inserted documents. (ie, you can define the "LastName" as being the element 'lastname') - which effectively updates an index for every document added to the collection that has an element 'lastname'.

You can then perform an SQL query, using any one of these columns, like 'lastname' within the query to restrict/select the JSON documents you are after.

I think this new feature will satisfy your requirements . There is even a generic REST API that allows you to Add/Delete/Update JSON documents.

See: https://learning.intersystems.com/course/view.php?id=687 

HTH, 

Steve

Hi,

If you want to protect the database, start by creating a resource via the options Security Management > Resources  in  the management portal,  giving it an appropriate name that makes sense to you - for example, if your database is called "myAppDB", create a security resource "%DB_MYAPPDB".

Prefixing with '%DB' in the name is convention, not a requirement.  During setup, add a description, and, select whether by default, users have Read, Write and/or Use privileges.  

This is only the first step.  Now that you have an identifiable security asset you want to secure, you can proceed.

You need to decide how users that fall under this new role of yours, will interact with this DB, so you need to build up this role definition accordingly. Using the Security Management > Roles section, select your new role, and, add the Database resource that protects your database (in my example above '%DB_MYAPPDB'), identifying if users of this role can only READ or can also WRITE data in this database.

This action assigns the privilege for this database afforded to users who belong to this new role.

Actually working with this database, however, would require that you add some resources to this role.  For example, if these users are developers, and you want to give these developers access for development, then, add the %Development resource to your new role too.

You will also need to more than likely add a %Service_ type resource that allows users of this role service access into Cache, for example, via TELNET, or via ODBC, etc.  Your requirements will differ from others, but is Studio access is required, definitely include %Service_Object (Use).

Finally - have a look at a pre-defined Role on the system called a "%Developer" which is setup by default on most installations., and is something you can use for reference.  Have a look at this role, and its resources+permissions (privileges) you will see it has some databases under protection, and allows %Development, and a bunch of %Service_ resource types for allowing different access, as explained above.

Sincerely,

Steve

Hi,

If I understand you correctly, I think you want to know whether there is a function that you can invoke, from the condition field of a Business rule, that checks if a given date is in between two other dates.

If you want to see what functions are available, the best way is to get assistance from the Expression editor (that is invoked when you double-click in the Condition field, or click 'fx', on the main Business Rules definition window when the condition field is in focus)

Whilst in the Expression Editor, clicking 'fx' again, will list the available functions, and the editor will help you through the process of building an expression that includes the use of these functions, and wrapping them around AND, OR and other operators.

I would suspect, however, that by default, we do not supply an in-built Business Rules function for your current scenario - however - (and I think this is a powerful feature), you can create whatever custom function and add these to the ones already available.   When you create your function, this will appear in the Expression Editor and can be used just as if it came with Ensemble.

Building your own function for this purpose is easy, it is just a class that extends Ens.Rule.FunctionSet, and must follow some basic rules.  See the documentation here: 

http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=EGDV_adv_custom_utilfunctions 

Your function would take 3 arguments, value, date1 and date2 to determine whether the date in 'value' is in between date1 and date2.  Here I'm assuming the date format is CCYYMMDD, and I'm converting the incoming date to a numeric $horolog date, using the $zdh (or $zdateh) function.  Change accordingly if your date format is different.

Class User.CustomFunctions Extends Ens.Rule.FunctionSet
{

/// take 3 date values in CCYYMMDD format, (value, date1 and date2) and verify if value falls between date1 and date2
ClassMethod DateBetween(value, date1, date2) As %Boolean
{
if ($zdh(date1,8)<$zdh(value,8)) && ($zdh(value,8)<$zdh(date2,8)) quit 1
quit 0
}

}

Defining a class like the sample above in your Ensemble-enabled namespace and compiling it, will expose this function (and the comment after the 3 '/') to the Ensemble Expression editor like any other function that already comes with Ensemble.

Hope this helps.

Steve

Hi Soufiane

The graphical rules editor used in the UI generates a class, and an xml block in that class, to represent your rules.

If you want a target to be different, based on some code, why don't you create multiple conditions for the different targets you have, then, base each condition on some database setting.

The rule itself remains static (except when you need to define a new target)  and it will show all the possible paths that can be taken by the rule.

Then.. programatically...you change that value in the database which is behind all the conditional statements you have and thus - programatically, you effect a target change.

The other alternative is to use a Business Process. You can send your message to be handled and routed by a Business Process in BPL.  The process, can programatically resolve the name of the target component in a context variable (let's say, context.TargetName). After context.TargetName has been programatically resolved, make a BPL Call action, and for the Call action's property "target" don't hardcode a value.

Instead supply "@context.TargetName", and the message will be sent to whatever the value of context.TargetName is at that point in time.

Steve

Hi Stephen,

I would avoid using the system database CACHESYS to hold your application globals.

You should create another database that  is specifically intended to hold the globals which would be common to all the productions you are running.

To enable the globals residing in this one, common database, to be visible from your various production namespaces - you would "map" these using Global Mapping rules defined against your production namespaces.

See the System Management Portal's Namespace configuration screens, and the Global Mappings feature, or look here: 

http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GSA_config_namespace_addmap_global  

 

Sincerely,

Steve

Hi Kenneth

Your container is based on a ubuntu distribution per the "FROM ubuntu" command in the dockerfile.

I believe ubuntu by default comes with and uses the application "apt-get" to do a similar function as yum, so, your yum commands running inside the ubuntu container you are starting with needs to retrieve yum, or instead, use apt commands.

however .. you say you believe that yum is installed because you executed:

which yum
/usr/bin/yum

- so the question is - did you execute this inside the container or outside of it, ie, on your VM.  Your VM (although running UBUNTU16.04), may have had yum downloaded into it - but the base ubuntu container you are using for your container definitely thinks you need this.

Equivalent apt-get commands you can use perhaps,  in place of the yum ones would be:

RUN apt-get update \
  && apt-get install which tar hostname net-tools wget \
  && apt-get clean all\ 
  && ln -sf /etc/locatime /usr/share/zoneinfo/Europe/Prague

Try that -

sincerely,

Steve

John is absolutely right.

You cannot set this value.  In fact, I should have said in my earlier post that the advertised (documented) maximum number of connections per License Unit is and always has been only 12.

The fact it is 25, is somewhat common knowledge and is a sort of grace limit, however I always tell my customers that you should work on the assumption that InterSystems could eventually enforce the advertised number of 12. If this happens it should not come as a shock to anyone.

12 connections from a user interacting with Cache, coming in from the same address, should be ample.

Steve

Hi Carey,

As you probably realised, the intention of the business rule (and rule sets within a rules class) is to typically have 1 sets of rules that are applied to a message, but for which you could have multiple versions, based on an effective date/time period.  That is:  if the date is X run rules set# 1, but if the date is Y run rule set#  2.  

If date ranges overlap, than, whichever is the first valid date range in the order in which the rules sets are arranged, defines which set of rules is executed. This is important to remember for later...

You can create 'Rule Set #2' ahead of time, making sure that the effectiveBegin of rule set #2, is immediately after the effectiveEnd of rule set #1 (as you indicated you wanted).

However, the second rule set would need be essentially, a copy of the first set - except for the changes to an individual rule item(s) that you want a different behavior for.  

Admittedly, cloning a whole rule set to another copy is labor intensive via the UI, but, extremely easy if you open the generated class in Studio - as you can just copy/paste the XML elements between the <ruleSet> tags,  save and re-compile. After you have your second set,  make your edits to rule set 2's effective date range, and whatever rule changes needed.

The Delegate action sends the message to another rule definition altogether, and, the Send sends the message to any other business component, (which can be a routing rule).   Using these two actions, based on any condition regardless, would require you to build a new rule definition or component to act as their target which you said you did not want to do, so, they are out.

Now - What you *can* do is write a user defined function to retrieve a rule definition's second rule set date range, and, use the value from this function in a conditional statement that drives the behavior of any of your first rule set's rule items.  You must ensure that Rule Set #1, however, is always the one that ever gets executed and the system does not ever fall on to running rule set #2 - so - even though you put in  a date range for rule set #2, leave date ranges for rule set #1 blank or wide open, so it will be the first and only one that will qualify for execution every time. 

Warning: This is not standard use or best practice, and I'm not recommending you do this - as it will effectively negate the rules sets with effective periods feature. which in the future, you may want to use.   I would stick with the approach of cloning Rule Set 1 into Rule Set 2, setting an appropriate EffectiveStart/end ahead of time, and making the individual changes you need to take effect in the future. 

Steve

Hi Ryan,

The message that you pass to your SOAP-based business operation should (as you indicated in your 3rd bullet point), contain both the extracted HL7 data, and the authorization key you retrieved from the previous step.

I'm assuming your SOAP Business operation you are using in the last step has been automatically generated by the Studio wizards, so, you will have a Class Method for each web method of your SOAP service.

You need to edit the default generated versions of these methods the wizard gives you, in order to add your SOAP Header.

You can access   ..Adapter.%Client in this business operation to get access to the private instance of the web service client class, so, using

   Do ..Adapter.%Client.HeadersOut.SetAt(...)

You can set the headers for that particular message invocation.

Sincerely - Steve

Hi Scott,

As far as I'm aware, you do not need a license to use the DeepSee User Portal, as long as you don't need to use DeepSee Cubes, or DeepSee Queries (which needs to be licensed).

So if the information you want to present in a DeepSee User Portal type dashboard, can be sought directly via SQL Queries, etc - you can use iether:

(a) Ensemble DeepSee Dashboards (receiving data from Business Metric classes). See http://docs.intersystems.com/ens20152/csp/docbook/DocBook.UI.Page.cls?KEY=EGDV_bmetric#EGDV_bmetric_dashboard 

or

(b) DeepSee Dashboards based on KPI Class which are designed to use only SQL to extract a result set.

See:  http://docs.intersystems.com/ens20152/csp/docbook/DocBook.UI.Page.cls?KEY=D2MODADV_ch_kpi

Of course if you want more control over the UI, then go down the ZEN, ZEN Mojo, etc route.

Steve

Hi,

I agree here, with Cache Password Authentication, once authenticated, there isn't any callback of way of extending the authentication with another step (further authentication). 

However - depending on your exact use case, you may use %ZSTART. All processes call into the routine %ZSTART at verious line labels (depending if they are a background job, interactive job, etc).  

see: http://docs.intersystems.com/cache20152/csp/docbook/DocBook.UI.Page.cls?...

 At the stage where you are in %ZSTART, you have already been authenticated - and perhaps, this is where you can craft something to achieve the end result that you are after.  It's worth looking into.

Steve