Author |
Message
|
pottas |
Posted: Wed Feb 02, 2011 11:23 am Post subject: Repeating values stored in environment |
|
|
 Disciple
Joined: 27 Oct 2005 Posts: 185 Location: South Africa
|
Confusing, very confusing.
But I know someone will shed some light...
My environment, Message Broker Toolkit:
Version: 6.1.0.8
Build id: 6.1.0.8-20100805_1110
I store a structure in my environment that looks like:
Code: |
Environment
serviceResponses
SoapAction:CHARACTER:http://contracts.it.nednet.co.za/services/business-execution/2011-02-17/NMFDealer/
operationName:CHARACTER:DealerEnq
dealerEnq
info
DealerName:CHARACTER:JACQUES
DealerContactNumber:CHARACTER:0116857331
DealerContactPerson:CHARACTER:Jacques Pottas
BankName:CHARACTER:FNB
BankBranchCode:CHARACTER:06255
BankAccTpe:CHARACTER:CA
BankAccNumber:CHARACTER:101020343
ResultCode:CHARACTER:R00
ResultInvalidFieldList
ResultInvalidField:CHARACTER:Inv1
ResultInvalidField:CHARACTER:Inv2
ResultInvalidField:CHARACTER:Inv3
ResultErrorBusinessMsg:CHARACTER:Error Business Message
ResultInfoBussinesMsgList
ResultInfoBussinesMsg:CHARACTER:Business Info Message 1
ResultInfoBussinesMsg:CHARACTER:Business Info Message 2
ResultInfoBussinesMsg:CHARACTER:Business Info Message 3 |
and in a subsequent compute, I have ESQL that simply need to extract the values from the structure 'ResultInvalidFieldList':
DECLARE totInvFld INTEGER CARDINALITY(Environment.serviceResponses.dealerEnq.info.ResultInvalidFieldList.ResultInvalidField[]);
... but the above esql result gives me back 0 (zero). Even though the Environment count is 3 for this structure.
Even when I try to select a value from this structure, I get a big empty:
DECLARE vValue CHARACTER Environment.serviceResponses.dealerEnq.info.ResultInvalidFieldList.ResultInvalidField[1];
Thanks in advance for the assistance.. |
|
Back to top |
|
 |
lancelotlinc |
Posted: Wed Feb 02, 2011 11:43 am Post subject: |
|
|
 Jedi Knight
Joined: 22 Mar 2010 Posts: 4941 Location: Bloomington, IL USA
|
Your attempt to store this information (IMHO) would be best served by using a Singleton that saves the info in a HashMap or HashTable.
In its basic essence, you are saving state information for retrieval on possibly a Request-Reply pattern. While it is possible to do what you are doing, it may be more expedient to use HashMap, etc.
If you are interested in doing this, let me know and I'll walk you through the code.
Others may have a different opinion, which is perfectly fine. _________________ http://leanpub.com/IIB_Tips_and_Tricks
Save $20: Coupon Code: MQSERIES_READER |
|
Back to top |
|
 |
mqjeff |
Posted: Wed Feb 02, 2011 11:56 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
That appears to be Debugger output of the Environment tree, rather than Trace node output.
You don't indicate if, for example, you have actually stored this data in the Environment tree under a parser that would preserve the namespace declarations that might have existed on the original data.
You don't indicate what is between the two compute nodes, such that we'd know if it was reasonable for the Environment to carry through. This is all still the same flow, right? and not crossing any Input node boundaries that might create a new message flow thread with a new Environment?
What does usertrace show for how the ESQL is being resolved and executed? |
|
Back to top |
|
 |
pottas |
Posted: Wed Feb 02, 2011 11:57 am Post subject: |
|
|
 Disciple
Joined: 27 Oct 2005 Posts: 185 Location: South Africa
|
Thanks for the reply.
Yes, please, walk me through the code.
Just to give you some background.
I have to do a number of service calls to external parties and reply to the original requestor of the service with a consolidated message. So the attempt is to do all the calls, store it in the Environment and then build a reply back to the requestor.
But, as stated, I get issues getting the cardinality and values from the repeating structures in the stored environment. |
|
Back to top |
|
 |
mqjeff |
Posted: Wed Feb 02, 2011 12:04 pm Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
Service calls using *what* node?
SOAPRequest? HTTPRequest? MQOutput? |
|
Back to top |
|
 |
lancelotlinc |
Posted: Wed Feb 02, 2011 12:06 pm Post subject: |
|
|
 Jedi Knight
Joined: 22 Mar 2010 Posts: 4941 Location: Bloomington, IL USA
|
To begin with, please review the Wikipedia article on Singletons.
http://en.wikipedia.org/wiki/Singleton_pattern
Next, in your Request message flow, place a JCN. Inside this JCN, call the Singleton and pass in the structure to the whole message (or any subset you want), along with a key value, perhaps the MsgId.
Lastly, in your Reply message flow, place a JCN. Inside this JCN, call the Singleton and retrieve the original structure by the key value, if the downstream copies MsgId to CorrelId, then this would be CorrelId.
Simple?
Here's more tutorial.
http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html
Best of luck. Lance. _________________ http://leanpub.com/IIB_Tips_and_Tricks
Save $20: Coupon Code: MQSERIES_READER |
|
Back to top |
|
 |
Vitor |
Posted: Wed Feb 02, 2011 12:06 pm Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
pottas wrote: |
I have to do a number of service calls to external parties and reply to the original requestor of the service with a consolidated message. So the attempt is to do all the calls, store it in the Environment and then build a reply back to the requestor. |
And you're not using the Aggregate nodes because.....?  _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
fjb_saper |
Posted: Wed Feb 02, 2011 12:08 pm Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Did you think about using an aggregation pattern?  _________________ MQ & Broker admin |
|
Back to top |
|
 |
pottas |
Posted: Wed Feb 02, 2011 12:13 pm Post subject: |
|
|
 Disciple
Joined: 27 Oct 2005 Posts: 185 Location: South Africa
|
Thanks guys.
To answer your question about aggregation, I need to make every subsequent call based on the result of the previous call.
So, as an example:
call 1: Locate the Customer;
call 2: Get the Customer Details;
call 3: Get the Customer Relationships;
...and then consolidate a response to the requestor with all the gathered data.
...and also, yes, all are SOAP calls to external (3rd party services) clients. |
|
Back to top |
|
 |
smdavies99 |
Posted: Wed Feb 02, 2011 12:30 pm Post subject: |
|
|
 Jedi Council
Joined: 10 Feb 2003 Posts: 6076 Location: Somewhere over the Rainbow this side of Never-never land.
|
Where do you store the data that you use to refer to in the next request?
We have something similar at my site. We have a process that goes out to several external suppliers that use SOAP and HTTP requests. We store the intermediate data in a table. Then a trigger process kicks off the next round of operations. We need delays because some of the external suppliers make SOAP Calls back to us with their results.
The downside is that the whole thing is a complete nightmare to debug & maintain. The Context dependand bits are a nightmare of spaghetti wiring.
Please try to separate out bits rather than trying to do everything in one big flow. One that does everything. _________________ WMQ User since 1999
MQSI/WBI/WMB/'Thingy' User since 2002
Linux user since 1995
Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions. |
|
Back to top |
|
 |
pottas |
Posted: Wed Feb 02, 2011 12:39 pm Post subject: |
|
|
 Disciple
Joined: 27 Oct 2005 Posts: 185 Location: South Africa
|
smdavies99, thanks.
Yes, sounds like we have a similar pattern (read challenge...)
The only difference is, I store the returned data in my environment.
So, once i have all the required data, I start interrogating it. Once I am happy that I can consolidate a reply, I attempt to build it and get it back to the requestor.
As for your suggestion :
Quote: |
Please try to separate out bits rather than trying to do everything in one big flow. One that does everything. |
I use a pattern with 'Label' nodes, calling SubFlows, and once I am happy, I build the response. Reason for using SubFlows, in the service as a whole, I can re-use them. All my flows are also separated into Broker Schema's (enterprise, operational and client Schemas). |
|
Back to top |
|
 |
smdavies99 |
Posted: Wed Feb 02, 2011 12:47 pm Post subject: |
|
|
 Jedi Council
Joined: 10 Feb 2003 Posts: 6076 Location: Somewhere over the Rainbow this side of Never-never land.
|
Oh dear. That is what we are faced with. Remember that when you make a change to one subflow you pretty well have to retest the whole schebang. You can't be sure that one change has not messed up another bit of the code.
We've just gone through a total rework process. Now all the subflows are separate flows with the data passed as WMQ Messages or in tables. Now it is all a lot more controllable and manageable. _________________ WMQ User since 1999
MQSI/WBI/WMB/'Thingy' User since 2002
Linux user since 1995
Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions. |
|
Back to top |
|
 |
mqjeff |
Posted: Wed Feb 02, 2011 12:52 pm Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
It's probably a good idea to get it working as a set of subflows first, and then work on refactoring it to break it apart into maintainable units.
Then, essentially, all you're really changing is the location that you look for the stored data, rather than trying to make sure you're storing the data correctly in the first place.
I suppose, conversely, it's just as easy to work on designing a Pattern that makes a series of requests across multiple flows, and then aggregates the responses, and then adjust the request and agreggation logic to match the specific instance once you've gotten the Pattern working.
It's still not clear why your current flow isn't working. |
|
Back to top |
|
 |
pottas |
Posted: Wed Feb 02, 2011 12:57 pm Post subject: |
|
|
 Disciple
Joined: 27 Oct 2005 Posts: 185 Location: South Africa
|
Well, as for your suggestion:
Quote: |
We've just gone through a total rework process. Now all the subflows are separate flows with the data passed as WMQ Messages or in tables. Now it is all a lot more controllable and manageable. |
I think we will have to do the same. At least it is still early times in the project, so it is still something we can get in place.
An update to my question:
If I store my response in my environment, specifying the parser as XMLNSC, I can get my data out of the environment:
SET OutputRoot.XMLNSC.test.testing2 = CARDINALITY(Environment.variables.XMLNSC.dealerEnq.dlr:ResultSet.dlr:ResultInfoBussinesMsgList.dlr:ResultInfoBussinesMsg[]);
Result: 3
SET OutputRoot.XMLNSC.test.testing3 = Environment.variables.XMLNSC.dealerEnq.dlr:ResultSet.dlr:ResultInfoBussinesMsgList;
Result:
testing3
ResultInfoBussinesMsg:CHARACTER:Business Info Message 1
ResultInfoBussinesMsg:CHARACTER:Business Info Message 2
ResultInfoBussinesMsg:CHARACTER:Business Info Message 3
But then I have to specify the namespace.
Why the first request didn't work, I'm not sure. Seems you have to give the environment (at least in this case) a parser (XMLNSC) and define the namespace.
Pity. |
|
Back to top |
|
 |
mqjeff |
Posted: Wed Feb 02, 2011 1:20 pm Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
It depends entirely on what you have done to save the data into the Environment in the first place.
If you have done the right thing, and created an XMLNSC tree in the Environment tree, then of course you have to use full XMLNSC paths to access the data.
If you hadn't, you wouldn't have preserved the namespace when you wrote the data into the Environment Tree, because the Environment tree doesn't have a parser. |
|
Back to top |
|
 |
|