Author |
Message
|
isaw |
Posted: Wed Nov 07, 2007 2:09 am Post subject: How to calc length of constructed message? |
|
|
Apprentice
Joined: 09 May 2007 Posts: 45
|
Hey guys,
I have an mxsd which is used to generated a CWF message which is MQ'd out to a system. And this works fine.
My mxsd has a message defined. That message has various local elements, each of which is a defined type. Those types have multiple elements & attributes assigned. Here's a basic description of what it's like:
Code: |
MainMessage
|
|__FixedArea (of type t_FixedArea)
| |__ messageId (xsd:string)
| |__ messageType (xsd:int)
| |__ rootArea (xsd:int) [0/1]
| |__ descripArea (xsd:int) [00/10]
| |__ ...more...
|__RootArea (of type t_RootArea) [min 0, max 1]
| |__ ...elements...
|__DescripArea (of type t_Descrip_Area) [min 0, max 10]
|__ ...elements.... |
So my types RootArea and DescripArea have min/max occurances based (referenced) on the specific elements in the FixedArea, rootArea & descripArea.
Keeping in mind that the values for rootArea and descripArea are set by an incoming XML file and therefore making them dynamic in number, I need to eventually calculate the "entire" length of the eventual CWF file after I'm done the ESQL. Sometimes I might have 3 DescripAreas, othertimes 8, etc. Maybe 1 root area, maybe 0.
And that's where I'm stuck. I don't know how to dynamically "count" the total character length of my finished CWF output message.
I have read that what I need to do is convert what I have constructed/assigned into a BLOB and then get the length of that which should tell me how long (how many chars) my CWF will be.
I've tried things like:
Code: |
SET poopers = CAST(OutputRoot.MRM.MainMessage AS BLOB CCSID InputRoot.Properties.CodedCharSetId);
SET c = LENGTH(poopers); |
But no luck -- I am just losing the plot on how to convert my current OutputRoot.MRM.MainMessage into a BLOB and account for the dynamic range of min/max areas and then get a "total length".
If someone could point me in the right direction I'd appreciate it. |
|
Back to top |
|
 |
Vitor |
Posted: Wed Nov 07, 2007 2:18 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
You could try ABITSTREAM _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
isaw |
Posted: Wed Nov 07, 2007 2:24 am Post subject: |
|
|
Apprentice
Joined: 09 May 2007 Posts: 45
|
I think I've just found my issue.
I'm trying to cast & determine the full length of my CWF *before* it's been serialised. I'm doing this at the end of my ESQL in the compute node. And in doing so, I'm playing with the logical view, not the physical view, aren't I ?
Hmm..
I suppose I could slap this compute node out to a RCD node and then to another compute node which converts it to a BLOB and then counts up the length. By that point it should be playing in the physical view. |
|
Back to top |
|
 |
Vitor |
Posted: Wed Nov 07, 2007 2:53 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
isaw wrote: |
I think I've just found my issue.
|
I think you're right  _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
isaw |
Posted: Thu Nov 08, 2007 7:10 am Post subject: |
|
|
Apprentice
Joined: 09 May 2007 Posts: 45
|
Well, I can get it to work but am a bit confused on the "options" and use of BITOR().
At the moment I can do this:
Code: |
SET CURRENT_MSG = CAST(ASBITSTREAM(OutputRoot.MRM.security_tmi_Body CCSID InputRoot.Properties.CodedCharSetId SET <myset> TYPE <mytype> FORMAT 'CWF') AS CHARACTER CCSID InputRoot.Properties.CodedCharSetId);
SET MAIN_MSG_LENGTH = LENGTH(CURRENT_MSG); |
And it works.
However, what's happening is it's giving me the *entire* message length from the OutputRoot.MRM level and not the OutputRoot.MRM.security_tmi_Body level. So instead of an "expected" length of say, 1000, I'm getting 4000.
I know the reason -- without using the "OPTIONS" clause in the ASBITSTREAM it defaults to the "RootBitStream, ValidateNone", hence why I get the length of my full message and not a sub-area.
In order to get the sub-area I need to use the FolderBitStream. But this is where my problem is -- I cannot figure out how to use the BITOR() and still get the "ValidateNone" to work.
As soon as I specify:
Code: |
DECLARE optionsList INTEGER BITOR(FolderBitStream,ValidateNone); |
And then use that in my ASBITSTREAM function:
Code: |
SET CURRENT_MSG = CAST(ASBITSTREAM(OutputRoot.MRM.security_tmi_Body OPTIONS optionsList CCSID InputRoot.Properties.CodedCharSetId SET <myset> TYPE <mytype> FORMAT 'CWF') AS CHARACTER CCSID InputRoot.Properties.CodedCharSetId); |
It fails with a message like, "Cannot get null value for a null Integer" or something to that effect.
Essentially I want to use the FolderBitStream and ValidateNone. But no luck. I checked the ASBITSTREAM spec and I was sure I could mix the FolderBitStream & ValidateNone integers but maybe not...?
Any suggestions? |
|
Back to top |
|
 |
EddieA |
Posted: Thu Nov 08, 2007 9:20 am Post subject: |
|
|
 Jedi
Joined: 28 Jun 2001 Posts: 2453 Location: Los Angeles
|
Well, the doc does state: "Some parsers also support another mode, FolderBitStream...", but doesn't say which.
Maybe you could test it without the Validate option, and the CAST, first, to make sure you can get what you need.
Cheers, _________________ Eddie Atherton
IBM Certified Solution Developer - WebSphere Message Broker V6.1
IBM Certified Solution Developer - WebSphere Message Broker V7.0 |
|
Back to top |
|
 |
kimbert |
Posted: Thu Nov 08, 2007 11:21 pm Post subject: |
|
|
 Jedi Council
Joined: 29 Jul 2003 Posts: 5542 Location: Southampton
|
When you use FolderBitstream mode, your TYPE parameter needs to specify the full path ( in the message definition ) from the root of the message to the element at which you want to start. So you need something like this ( not tested, of course )
Code: |
SET CURRENT_MSG = CAST(ASBITSTREAM(OutputRoot.MRM.security_tmi_Body OPTIONS optionsList CCSID InputRoot.Properties.CodedCharSetId SET <myset> TYPE <mytype>.security_tmi_Body FORMAT 'CWF') AS CHARACTER CCSID InputRoot.Properties.CodedCharSetId) |
|
|
Back to top |
|
 |
isaw |
Posted: Mon Nov 12, 2007 5:12 am Post subject: |
|
|
Apprentice
Joined: 09 May 2007 Posts: 45
|
OK, just given that a try and it's failing with an error that so far Google hasn't given me an answer for:
"Can't get value for null integer value"
I mean, literally speaking I understand that, but what i don't understand is what in my code/MRM is causing this.
One of the requirements/constraints I have to work with is that the destination system this CWF message will eventually go to requires any and all fields (400+) with no explicitly set value come in as asterisks to indicate to the dest machine to use its own defaults. So one of the chaps here suggested that when I created my MRM, from a basic COBOL copybook, I ensure that everything was 'nillable' with a value of "*".
That way, when i create my various areas in ESQL, I can set them to NULL first which ensures all the fields (int, shorts, strings, etc) have the defaults of "*" in them to start with:
Code: |
SET OutputRoot.MRM.security_tmi_Body.tmi_s_RequiredFixedArea.* = NULL; |
And then I can gi thru them and manually assign the values as required:
Code: |
SET OUTPUT_FIXED.modeType = modeType;
SET OUTPUT_FIXED.securityNumber = INB_XML.inst:InvOneInstrRef;
SET OUTPUT_FIXED.rootArea = 1;
SET OUTPUT_FIXED.bondArea = 0;
SET OUTPUT_FIXED.derivativeArea = 1;
SET OUTPUT_FIXED.userDefinedArea1 = 1;
SET OUTPUT_FIXED.descMsg = INB_XML.inst:DescMessage;
... ad nauseum... |
And this does work fine -- so long as I skip using ASBITSTREAM, it is successfully serialised and sent out via the output node and goes up to the dest machine fine, etc. It's only when I use ASBITSTREAM, but the optional 'OPTIONS FolderBitStream' does it blow up and give me that error above.
Has anyone else hit this error? |
|
Back to top |
|
 |
jefflowrey |
Posted: Mon Nov 12, 2007 5:15 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
isaw wrote: |
That way, when i create my various areas in ESQL, I can set them to NULL first which ensures all the fields (int, shorts, strings, etc) have the defaults of "*" in them to start with: |
No, that may not do that at all. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
isaw |
Posted: Mon Nov 12, 2007 5:46 am Post subject: |
|
|
Apprentice
Joined: 09 May 2007 Posts: 45
|
Ahh. Oops. The follies of accepting what others have said at face value
Well, this is what I was told to do in order to ensure all the fields had "*" in them. Again, being very very new to this I didn't have the knowledge to question, only to accept and get on with it due to deadlines.
If there is a better way to ensure all fields have a default of "*" (obviously with the correct number as defined in the original cobol copybook), which could fix my other issue, what would you suggest? |
|
Back to top |
|
 |
jefflowrey |
Posted: Mon Nov 12, 2007 6:05 am Post subject: |
|
|
Grand Poobah
Joined: 16 Oct 2002 Posts: 19981
|
It may have nothing to do with your actual problem. I'm not entirely sure if FolderBitStream will tell the CWF parser to construct default values or not. _________________ I am *not* the model of the modern major general. |
|
Back to top |
|
 |
isaw |
Posted: Mon Nov 12, 2007 6:58 am Post subject: |
|
|
Apprentice
Joined: 09 May 2007 Posts: 45
|
There we go. Sorted.
Ok, it *was* down to how I was using the NULL of the area. Instead of nulling the field values, it was, as you pointed out, nulling the fields themselves.
So a quick changed from:
Code: |
SET OutputRoot.MRM.security_tmi_Body.tmi_s_RootArea.* = NULL; |
to :
Code: |
CREATE FIELD OutputRoot.MRM.security_tmi_Body.tmi_s_RootArea; |
Seems to have resolved it. My ASBITSTREAM now works and picks out *only* the area I want.
Now getting a "Node is an unknown type (Unresolved Choice, Named or Value)" but that seems to be a typical WMB toolkit issue, of which I have already found several posts on here on how to handle.
Thanks for the heads up on that Jeff! |
|
Back to top |
|
 |
|