Steve Pisani · Dec 16, 2015 go to post

Thanks Stefan.

I had read that, and understand how with SOAPSESSIONs enabled, soap calls can utilise the same session on the back-end.  My tests definitely show this working.

What I was hoping to discover however, is if license unit consumption is effected or not effected, with the SOAPSESSION=1 model, which is what is implied by the comment against the parameter which says ".Also effects license consumption".

My tests show that license unit consumption for SOAP requests that are session based are no different to others - so - I still can't see that there are an license unit consumption implications.

In fact - it seems that no SOAP calls seem to be consuming licenses in the scenarios I have tested described below when using SOAP UI from an different IP address to the web service server...:

(a) with and without SOAPSESSION=1 set (and where set, CSP header is used by the web client)

(b) with or without Unauthenticated or Password access set on the CSP Application.

(c) with a hang of,say, 10 seconds in the web method (allows me to gather license counts).

(d) web service hosted as a standalone Cache web service, or, as a webservice that's part of a Business Service in a running Ensemble production (csp Gateway used for access).

In all scenarios and combinations of each above, it seems, no license units are consumed at all.  I would have expected that (at least for SOAPSESSIONs enabled) a license unit would have been consumed for the duration of the session.  My tests do not confirm this, hence the question on trying to clarify what the license implication actually are.. :)

Perhaps a broader understanding of how SOAP requests consume and then release license units is a better approach to addressing this thread.

(Note that my license key does not have the Web-Add option enabled. This is 2015.1.)

Steve

Steve Pisani · Jan 6, 2016 go to post

Good question re multiple SOAP requests in parallel.(ie - 2 simultaneouse SOAP requests that have the same CSPCHD soap header identifying the same SOAP Session, send simulateously to the web service).  

I have tested this. I sent two SOAP-Session enabled web service requests to the same web service and method, exactly 5 seconds apart. They both used the same session ID in the soap message.  The SOAP Service hung for 30 seconds, then, returned the server time.

The responses messages where received, one after the other, in the order they where sent, and 5 seconds apart, so it seems that they are queued FIFO.

Steve

Steve Pisani · Jan 6, 2016 go to post

This is correct, and I have been testing this.

Ensemble E-type licenses do not count license units for SOAP service calls into Ensemble. This is true regardless of wether the user is identified, un-identified, or, SOAPSESSION is in play.

With Cache or Ensemble C-type licenses, License units are counted, and additionally, if anonymouse identity is used, a minimum 10 second grace period must be consumed for the connection regardless. 

Thanks - Steve

Steve Pisani · Jan 6, 2016 go to post

Hi,

I have run some tests in order to answer my own question on this thread, and that is - what are the licensing implications of using SOAPSESSION for web services hosted within Ensemble (E-type). I thought its worth posting the answer here for completeness.

Given that Ensemble E-Type licenses do not consume license units, there are no license implications that I can see.  Sure the CSP Session hangs around for the duration of the SOAPSESSION calls until the user decides to end it, but, the license count (seperate from the CSP Sessions) is not effected and remains unchanged.

Thsi is not true for Cache or Ensemble C-type licenses. With the license unit consumed at the begining of the SOAP session, and, with the session on the back-end persisting for all subsequent SOAP Service calls from the web client, until the session expires, or is programatically ended - one needs to be aware that the license unit remains in use for this whole period.  

It becomes critical that SOAP applications that that implement SOAPSESSIONS make sure their session are correctly terminated with the back-end when  it is no longer needed, otherwise, the license unit will remain in use for, at least,  the session timeout number of seconds defined against the web application.

Steve

Steve Pisani · Jan 14, 2016 go to post

Hi Scott,

On initial investigation at least, it certainly seems like the property 'Source' on the message header, returns only the root folder path ie, "/incoming",  not the subdirectoryr path when you have used the Subdirectory Levels settings of the FTP adapter.

One option perhaps would be to see if there is some other information in the HL7 Message data (Source system ?  Source Facility ?) that could provide enough information for your business rule.

Another option would be to have multiple FTP_In business services, one for each sub-folder, although I realise this is inpracticle if the subfolder names aren't fixed, or, there could be many of them. 

Perhaps others in the community have a better approach (including subclasssing the product's Adapters perhaps) to exposing this detail.

Steve

Steve Pisani · Feb 16, 2016 go to post

Thanks, but in my question, when asking if "there is another (more elegant ?) way of achieving the same result without creating a the dimension ‘IsLastKnownRecord’ in the cube, but instead, directly as part of the pivot table."

I meant, is there a way of achiving the filtered results showing the last recorded date, using, only MDX syntax - (and not creating a dimension derived from the underlying source data).

Your solution assumes I have access to the source class and data model. If I do, then yes, i'll extend the underlying source data model in one of several ways (including that mentioned in a subsequent post).

Note also - that I still want to quert all logged events so setting a cube buildRestriction is not something I would be wanting to do.

thanks anyway,

Steve

Steve Pisani · Feb 16, 2016 go to post

This is a good idea.

But once again, though, the core question was whether MDX afforded me syntax, that would show only the latest RelocationDates for distinct CitizenRef's found.

(so - assume, my source table only has ID, CitizenRef, RelocationDate, City and Surname fields, and cannot be modified).

Thanks for the suggestion though.

Steve

Steve Pisani · Feb 24, 2016 go to post

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

Steve Pisani · Mar 9, 2016 go to post

Hi Mark, just on the ECP comment, I thought the ECP clients would define their ECP server using the VIP of the mirror set.

Can you explain here how you would you configure the ECP clients without a VIP address for the mirror set?

Thanks

Steve

Steve Pisani · May 1, 2016 go to post

Hi,

I removed jquery-1.10.2.min.js and left jquery-1.11.3.min.js.  however, the problem still exists. 

Steve

Steve Pisani · May 2, 2016 go to post

Ah.. I did not realise the order was important.

after switching and loading jQuery first, and jQM later - it worked.

Thanks.

Steve

Steve Pisani · Jun 21, 2016 go to post

Hi,

What I was hoping to do is programatically set the 'default' Enabled/Disabled status of a configuration item,  - ie - editing the XML in the production class.  We do this from the Management Portal so that when a I disable a component, stop the production and re-start it, the component is still disabled.

I don't want to run the risk of messages starting to flow into the production namespace, by starting the production, then, OnStart - (which presumably kicks off after all queues have been setup and business services start 'listening'),  subsequently start disabling some components.

Steve

Steve Pisani · Jun 22, 2016 go to post

Hi John,

afaik, settings between DEV and PROD are different, and they are using System Defaults to succesfully apply different settings.

See my solution below

Steve

Steve Pisani · Jun 22, 2016 go to post

Hi 

Thanks Eduard for trying and for John's comments.

Brendan - Actually... - I tried using the SaveToClass() method as you described before I posted my question to the community, but, it my initial tests showed it deleting the entire contents of my XDATA block.  I was not confident that was the way to go - hence the question, thinking there might have been another API.

However - spurred on again today by yourself coming to the same idea I already had, I decided to give it another look - and - I have solved the problem.

For all - I want to re-iterate - this is how to set the Enabled configuration status of a business host by modifying the XML in the production class's XDATA block.  For run-time enabling/disabling, use EnableConfigItem method of Ens.Director.

If the enabled status changes you want to make are to the production's configuration, then - here is the solution:

/// productionName = Package.Classname
/// 
Items(ConfigItem)=startupStatus 
///

/// ConfigItem = must contain the fully qualified reference of: ConfigName|ClassNameOfComponent
///                            due to config items, that can be defined as the same name multiple times in a production
/// startupStatus = 1 or 0 (true or false respectively)
/// 
ClassMethod UpdateClassEnabledStatuses(productionName As %String, ByRef Items As %String) As %Status
{
set tSC=$$$OK 
Try {
set statProdRunning=##class(Ens.Director).IsProductionRunning(productionName)
if statProdRunning=1 {
  // Stop Production
  set tSC=##class(Ens.Director).StopProduction()
  if $$$ISERR(tSC) {
    write !,"Unable to stop production. Exiting without changes."
    quit 
   }
}
// take out an exclusive lock on the class to avoid being edited remotely.
lock +^oddDEF(productionName)#"E":5
if '$t {
 write !,"Unable to lock production class. Exiting without changes."
 quit 
}
// iterate through items.
set objProd=##class(Ens.Config.Production).%OpenId(productionName)
if '$IsObject(objProd) {
  write !,"Production configuration for production: "_productionName_". couldn't be found. Existing without changes."
  quit
}
set ci=""
for  {
  set ci=$order(Items(ci)) quit:ci=""
  set fqConfigItem=productionName_"||"_ci
  // change the status in the class.
  set objConfigItem=objProd.FindItemByConfigName(fqConfigItem)
  set objConfigItem.Enabled=Items(ci)
  write !,"Updating item: "_$piece(ci,"|")_" ("_$piece(ci,"|",2)_")"_" to: "_$select(Items(ci):"True",1:"False")
 
  set err=objProd.SaveToClass(objConfigItem) if $$$ISERR(err) write " - Failed" continue
  set err=objProd.%Save() if $$$ISERR(err) write " - Failed" continue
}
// release exclusive lock the class
lock -^oddDEF(productionName)#"E"
// Reset the running status of the production
if statProdRunning=1 {
  do ##class(Ens.Director).StartProduction(productionName)
}
catch exceptionvar {
  lock -^oddDEF(productionName)#"E"
  set tSC=exceptionvar.AsStatus()
}
  quit tSC
}
 

Steve.

Steve Pisani · Jun 23, 2016 go to post

Hi,

just starting to look at it.  From a UI perspective - if you do not select an Instance, or Namespace filter in the display, the Name column fully qualifies the component by adding Instance:Namespace - which is great.  This make the column wider, pushing "Avg Que Time" and "Queue Trend" columns outside of the display are and invisible.  

There is no horizontal scroll bar to bring them back in.

Steve

Steve Pisani · Jun 24, 2016 go to post

Hi,

Using the new JSON support, is it possible to create a dynamic object from a JSON string, (eg objFromJSON) that will then allow  for objFromJSON.<property>  syntax on the dynamic object  to access properties in the JSON string.

Steve

Steve Pisani · Jun 27, 2016 go to post

excellent - thanks !...

But what about collections, say, a property 'b' that is a collection (with b1, and b2 keys)

>set objFromJSON = {}.$fromJSON("{""a"":""1"",""b"":[{""b1"":""x""},{""b2"":""y""}]}")
>write objFromJSON.a
1
>write objFromJSON.b
24@%Library.Array

>set arr=objFromJSON.b

 

I can only get to each item in 'b' by instantiating an iterator (using arr.$getIterator()), and looping through the list with the $getNext() method of the resulting iterator.   I can remove, get the last, add to the end and set an item in the collection.

I'm assuming there is no concept of getting the item #1 from the collection - using '1' as the key, indicating the first in the collection, or getting #2, indicating the second item - something like

set bObject=arr[1] or  set bObject=arr.GetAt(1) or bObject=arr.Get(1) ?

Steve

Steve Pisani · Jul 1, 2016 go to post

Hi.

I have made a correction to the post, and associated sample code, to indicate the correct way that long-handed versions of custom commands, functions and variables need to developed.  Code that is implemented as a function with arguments needs to explicitly invoke the short-hand logic, or the functionality will not get invoked when using the long-handed command.

Thanks

Steve

Steve Pisani · Aug 26, 2016 go to post

Hi Stefan,

I guess that's not how it is described under 'Event Handling' here:  http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY…  which incorrectly implies that that Zen Mojo will call onevent for anything other than onselect or onchange.  

So: in my ZENPage, I've overridden onkeydownhandler(evt), and I intend to call the onevent() method in my template class, which will have all the logic for all the events other than onsearch and onclick.

The zenPage onkeyuphandler gives me evt, which I can use to get the HTML DOM id of the component that raised the event.  (id=evt.srcElement .id).

How do I go about finding the layout object's  key attribute, given the DOM id ?

Steve

Steve Pisani · Aug 31, 2016 go to post

Thanks Bernd.

My issue is actually managing to get the onevent() method in the template class to be fired at all.  

I'm currently trying to determine what code is required to register onKeyUp() events to be captured for specific layout objects -  that would result in the onevent() in my template class gets invoked (with the evt, key, value and docViewId arguments passed).

Have you use the onevent method callback in the template class ?

Steve

Steve Pisani · Sep 2, 2016 go to post

Thanks Bernd,

I see that onkeypress works- just as I expected it to firing onevent(). you're right.-

But - I was trying to capture onkeyup - which does not get fired into the onevent().

For onkeyup, and probably other events, we need to implement this manually. We would need to resolve the element id of the layout object, then, register an event listener for the event occurring on that element  - which when fired, would invoke onevent() in the template class.    (as per Steve Whitemen's next post)

thanks - 

Steve Pisani · Sep 20, 2016 go to post

Hi Lutz - 

I'm assuming you have a small typo above and you intended to use "$ZF" not "$F"

Steve

Steve Pisani · Jan 18, 2017 go to post

Hi,

I'm wondering... Is it possible to have a single dashboard that represents metrics from multiple Cache instances  - for example, if I have 3 Cache instances installed on separate servers , and I want to see on a single dashboard, then % license usage graphs from each instance, represented in separate widgets.

Steve

Steve Pisani · Jan 19, 2017 go to post

I too am having a problem installing this.

I'm using the "source installation" instructions.

Can someone verify please what are the true list of prequisites needed (other than Cache 2016.1) for this.  Please make no assumptions that node.js, or, Python, of any version, is already installed on the target server..

Thanks - Steve

Steve Pisani · Jan 22, 2017 go to post

I needed version 6 (not 7) of NodeJS and had to run

npm install -global --production windows-build-tools

...From an elevated powershell or DOS prompt (running as administrator), to get the UI installed.

Steve