Dynamic Object as a request to Business Process

Hi,

I am sending a request message to Business Process which has one property as Dynamic Object type. So i get the JSON in my REST service and convert that as a dynamic object and set that in the request message and calling the business process from the business service. But the request is not getting sent to the Business Process. Is it possible to send dynamic object input to the business process.

  • 0
  • 0
  • 144
  • 13
  • 3

Answers

Any message in Ensemble is a persistent object.
If you persist your dynamic object as (long)  %String or %Stream it should get sent

Thanks Robert for your reply. I tried that as a %String but when i try to retrieve the value in business process i get an error.

I have a persistent class with a string property and i set that value as the dynamic object. Now that persistent class is my request to the business process. Here is my property

Property Test %String;

Set classObj.Test = DynamicObject (I have created this from my JSON request - I can't define the dynamic object since it can have any different values and i get these dynamic values in my business process based on some logic, basically i dont have a defined set of properties for my dynamic object so i just have to pass that to my business process)

Now if i try this,

w request.Test.%Get("XYZ") (i know that XYX exists in my dynamic object)

i get an error "ERROR <Ens>ErrException: <INVALID OREF>zS1+2^" ...

But if i try to write the trace like request.Test then i get a result as dynamic object.. so the dynamic object seems to be there but i am not able to retrieve the value for some reason.

Shameer

You can't just set the dynamic object (exactly the oref) to  %String.
You place than just a reference of a local structure to your message.  That's useless.
you need to 

Set classObj.Test = DynamicObject.%ToJSON()

Now you have your string that gets persisted and is part of your message.

Suggested reading: Converting Dynamic Entities to and from JSON​

I have tried to set the above but getting the below error,

""error":"ERROR #5802: Datatype validation failed on property"

This is what i have tried ,

Set classObj.Test = DynamicObject.%ToJSON()

is it defined that way?
Property Test as %String (MAXLEN="") ;

ATTENTION - default MAXLEN = 50 !!!!!

This might look odd but try

set local= dynamicObject.%ToJSON()
set classObj.Test = local

 
so you see if the issue is your property  
or your dynamic Object. as there are 2 objects in the command.
the only thing %String is checked against is Length. 
otherwise. if %ToJSON() fails your dynamic object is broken somehow

I tried that exact same way but i am now getting a different error,

"error":"ERROR #5002: Cache error: <INVALID OREF

You didn't indicate the line you get the error.
anyhow the message is clear:
Either classObj or dynamicObject is not what you expect it to be.
If you test from Terminal you can use

ZWRITE classObj
ZWRITE dynamicObject

to see what they are.

otherwise, you may comment out one line and see if it still breaks e.g.

// set local= dynamicObject.%ToJSON()
set classObj.Test = "my dynamicObject = "_$ISOBJECT(dynamicObject)

So you see what happens.  I expect:  my dynamicObject = 0

So you see where you have to investigate further

That value is coming as 1, so we do have an object but if i store that as it is in the string property then i just get the reference (not the object) and if i try to convert that to ToJSON and store then i get the error, not sure if i am missing something

Pls. forget "store it as it is" all you store is the oref (a pointer to a local structure) with no persistent storage behind.

set local= dynamicObject.%ToJSON()
set classObj.Test = "my dynamicObject = "_$LENGTH(local)

so you don't get an error if you just apply  %ToJSON()  ???

 If your version is before 2016.2  than .$toJSON() would be the right method

OK. now we see that the dynamicObject is broken somehow

Just to be complete

Of course at the receiving end 

w request.Test.%Get("XYZ") 

This will fail now with <INVALID OREF>
Since request.Test is now of type %String and not a dynamic object.

You now need to recover your dynamicObject from %String

set dynObj={}.%FromJSON(request.Test)
write dynObj.%Get("XYZ")   


If you check it in the same process it's of course there as you are still in the same local partition (environment).
but you need it in your message that gets handled by some other process that has no access nor idea about your local environment.

which is the essential concept of all those message structures.

Tried that, not the best idea. Tracing and debugging become much harder and you can't query as easily via SQL.

Usually I work with JSON input in Ensemble like this:

  • Create persistent class with required properties
  • Instantiate it from incoming JSON
  • Send this persistent object to BP

As there is no further reaction at all I assume this is the summary of the solution:

dynamicObject -> Message to be sent

Property Test as %String (MAXLEN="") ;

Set classObj.Test = DynamicObject.%ToJSON()

 ​Message received -> dynamic Object​

set dynObj={}.%FromJSON(request.Test)
write dynObj.%Get("XYZ")