go to post Eduard Lebedyuk · Jan 4, 2018 s ^TMPPRD=reqObj That won't work. Global can store object serialization or some property value.
go to post Eduard Lebedyuk · Jan 4, 2018 sbJSON that actually get passed to XmlToJSONNode is not an object. Additionally try this modification to XmlToJSON (you need to specify file if you want to use file stream): Method XmlToJSON(xml As %Stream) As %Stream { set xmlDoc =##class(%XML.TextReader).ParseStream(xml,.textreader) set sbJSON =##class(%Stream.FileCharacter).%New() do sbJSON.LinkToFile("somefile") do sbJSON.WriteLine($C(123)) do ..XmlToJSONnode(sbJSON,textreader.Name,1) do sbJSON.writeLine($C(125)) return sbJSON }
go to post Eduard Lebedyuk · Jan 3, 2018 You can redefine these dynamic dispatch methods:%DispatchGetProperty / %DispatchSetProperty / %DispatchSetMultidimProperty%DispatchGetModified / %DispatchSetModified%DispatchMethod / %DispatchClassMethodAnd they are available for all classes.
go to post Eduard Lebedyuk · Jan 2, 2018 can't find properties Prop1, Prop2...etc in %ZEN.proxyObject documentation They are dynamic (defined via %DispatchGetProperty/%DispatchSetProperty) so you can assign any properties to %ZEN.proxyObject. CopyFrom in %Net.HttpRequest, you can find Write method but not the Copyfrom method so how do we suppose to know those properties and methods? Unable to reproduce (on 2017.2 though). You may try to use #Dim directive: #Dim Stream As %GlobalBinaryStream Set Stream = ##class(%GlobalBinaryStream).%New() Do Stream.Write("111") Set Request.EntityBody = Stream Autocomplete works better for variables defined with #Dim (also it's useful for lists/arrays with objects). what the Maximum Props we can have ? 1000 properties per class.
go to post Eduard Lebedyuk · Jan 2, 2018 Thank you, Robert. Missed that during copy&paste from terminal. Fixed.
go to post Eduard Lebedyuk · Jan 2, 2018 Here's a sample request with JSON payload from %ZEN.proxyObject, with object->json serialization via %ZEN.Auxiliary.jsonProvider: Set Body = ##class(%ZEN.proxyObject).%New() Set Body.Prop1 = "Val1" Set Body.Prop2 = "Val2" Set Array = ##class(%ListOfDataTypes).%New() Do Array.Insert(1) Do Array.Insert(2) Do Array.Insert(4) Set Body.Array = Array Set Request= ##class(%Net.HttpRequest).%New() Set Request.Server = "server" Set Request.Location = "location" Set Status = ##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject(Request.EntityBody, Body) Set Status = Request.Post() Payload looks like this: Do Body.%ToJSON() { "Array":[1,2,4 ], "Prop1":"Val1", "Prop2":"Val2" } Documentation on %Net. HttpRequest.
go to post Eduard Lebedyuk · Jan 1, 2018 I encountered somewhat similar problem, here are the conditions: Several types of business objectsBusiness objects may depend upon other objects, so it's like a dependency graphUpdates arrive for objects and they need to be approved by humansHumans approve updates randomlyBut updates should be applied top to bottom (so base object first, then all objects which depend on it, then all objects which depends on them and so on)Updates arrives continuously To solve this, we used deferred responses and the class I posted above except it also has dependsOn property which contained a list of tokens which should be satisfied before current token (message corresponding to current token) can be returned. It looked like this: Property dependsOn As List Of %String(SQLPROJECTION = "table/column", STORAGEDEFAULT = "array"); // Index dependsOnIndex On dependsOn (ELEMENTS); So our process was: if we found new dependency we added to list, if dependency was satisfied we removed it from all lists.If there was no more dependencies than update would be fired.Then there was a check to see if current update was a dependency for something else. Projecting list property as a table helped. Also collection properties are indexable, so it all worked quite fast.
go to post Eduard Lebedyuk · Dec 31, 2017 You'll need to develop the criteria yourself as it's heavily dependent upon your business logic. There's no common solution there. Generally you need to:Pass some unique identifier with your request (as one of request properties or in the filename or as a header, etc.).In your business service parse the response and determine what is this response to.Send deferred responseI usually have a Deferred token table where I keep track of tokens and objects to which they relate: #Include Ensemble /// Stored Deferred token. /// Assumption: one BH generates only one type of Deferred token. Class Production.DeferredToken Extends %Persistent { /// Token Property token As %String; Index IDKEY On token [ IdKey ]; /// Object's class anme Property objectContext As %Dictionary.CacheClassname; /// Object's primary key Property objectId As %String; Index objectIndex On (objectContext, objectId) [ Unique ]; /// Update ts (UTC) Property updatedOn As %TimeStamp [ Required, SqlComputeCode = { set {*} = $$$ts}, SqlComputed, SqlComputeOnChange = (%%INSERT, %%UPDATE) ]; /// Ensemble session Property sessionId As %Integer [ InitialExpression = {$get($$$JobSessionId)} ]; /// Ensemble BH Property configName As %Integer [ InitialExpression = {$get($$$EnsJobLocal("ConfigName"))} ]; /// Ensemble BH class Property ensembleContext As %Integer [ InitialExpression = {$get($$$ConfigClassName($get($$$EnsJobLocal("ConfigName")," ")))} ]; /// Tries to store a new token if possible /// w ##class(Production.DeferredToken).add() ClassMethod add(token As %String, class As %String = "", id As %Integer = "") As %Status { return:((class'="") && ('##class(%Dictionary.ClassDefinition).%ExistsId(class))) $$$ERROR($$$ClassDoesNotExist, class) return:((class'="") && (id'="") && ('$classmethod(class, "%ExistsId", id))) $$$ERROR($$$GeneralError, $$$FormatText("Object '%2' from class '%1' does not exist", class, id)) return:..IDKEYExists(token) $$$ERROR($$$GeneralError, $$$FormatText("Token '%1' already exist", token)) set obj = ..%New() set obj.objectContext = class set obj.objectId = id set obj.token = token set sc = obj.%Save() return sc } Use %ExistsId, %DeleId, objectIndexExists, objectIndexOpen to manipulate stored tokens.
go to post Eduard Lebedyuk · Dec 30, 2017 I think you need deferred response.It works like this:BP sends message to BOBO defers response and quitsBS (or anything else really) generates a response and sends it to BPBP receives deferred response
go to post Eduard Lebedyuk · Dec 30, 2017 Cache JDBC schema is: jdbc:Cache://<host>:<superserver_port>/<namespace> Documentation.
go to post Eduard Lebedyuk · Dec 29, 2017 Stop Caché.Start Caché in emergency mode.Modify admin password.Stop Caché.Start Caché normally.
go to post Eduard Lebedyuk · Dec 29, 2017 You can add Ens.ProductionMonitorService service to your production, which provides a monitor service for the production statusThe default behavior of this service is to call UpdateProduction once it notices the production is not up-to-date. Users can override the OnProcessInput method to customize the behavior. It would be enough to automatically restart relevant items and keep production up to date. Generally to access/manipulate info about Ensemble and it's hosts use Ens.Director class, i.e. UpdateProduction method.
go to post Eduard Lebedyuk · Dec 28, 2017 Pool size 4 would be better.Adding 4 same processes would only make production configuration more complicated.
go to post Eduard Lebedyuk · Dec 28, 2017 Maybe %NOFLATTEN can help, if we're sure that inner query returns few results.Also you can try to use IN.
go to post Eduard Lebedyuk · Dec 28, 2017 Also possible to use $$$NULL macro: do $$$AssertEquals(myObj, $$$NULL, "myObj is null")
go to post Eduard Lebedyuk · Dec 28, 2017 For example, Java Gateway Wizard is at: http:://host/csp/reg/%25ZEN.Template.ObjectGatewayWizard.JavaHome.cls I usually use "find in files" and search for page title to find where it is. [@Jeffrey Drumm]'s answer is way better.
go to post Eduard Lebedyuk · Dec 27, 2017 in my sample, it should be like P.id = P1.id and P1.id = P2.id.It would work like that too.Also, you self join on the identical fields "ID", so I guess the engine could infer p1.id = p2.id by "P.id = P1.id and P.id = P2.id" , this would interfere my intention.Please consider posting:sample classessample datadescription of data you want to getwhat data you want to getquery
go to post Eduard Lebedyuk · Dec 27, 2017 Yes. SELECT p.id, p1.id, p2.id FROM Sample.Person p LEFT JOIN Sample.Person p1 ON p1.id=p.id INNER JOIN Sample.Person p2 ON p2.id=p.id