ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » How to calc length of constructed message?

Post new topic  Reply to topic
 How to calc length of constructed message? « View previous topic :: View next topic » 
Author Message
isaw
PostPosted: Wed Nov 07, 2007 2:09 am    Post subject: How to calc length of constructed message? Reply with quote

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
View user's profile Send private message
Vitor
PostPosted: Wed Nov 07, 2007 2:18 am    Post subject: Reply with quote

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
View user's profile Send private message
isaw
PostPosted: Wed Nov 07, 2007 2:24 am    Post subject: Reply with quote

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
View user's profile Send private message
Vitor
PostPosted: Wed Nov 07, 2007 2:53 am    Post subject: Reply with quote

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
View user's profile Send private message
isaw
PostPosted: Thu Nov 08, 2007 7:10 am    Post subject: Reply with quote

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
View user's profile Send private message
EddieA
PostPosted: Thu Nov 08, 2007 9:20 am    Post subject: Reply with quote

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
View user's profile Send private message
kimbert
PostPosted: Thu Nov 08, 2007 11:21 pm    Post subject: Reply with quote

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
View user's profile Send private message
isaw
PostPosted: Mon Nov 12, 2007 5:12 am    Post subject: Reply with quote

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
View user's profile Send private message
jefflowrey
PostPosted: Mon Nov 12, 2007 5:15 am    Post subject: Reply with quote

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
View user's profile Send private message
isaw
PostPosted: Mon Nov 12, 2007 5:46 am    Post subject: Reply with quote

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
View user's profile Send private message
jefflowrey
PostPosted: Mon Nov 12, 2007 6:05 am    Post subject: Reply with quote

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
View user's profile Send private message
isaw
PostPosted: Mon Nov 12, 2007 6:58 am    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Page 1 of 1

MQSeries.net Forum Index » WebSphere Message Broker (ACE) Support » How to calc length of constructed message?
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.