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 » Custom WBIMB Node question

Post new topic  Reply to topic
 Custom WBIMB Node question « View previous topic :: View next topic » 
Author Message
heyandy
PostPosted: Tue May 10, 2005 1:58 pm    Post subject: Custom WBIMB Node question Reply with quote

Newbie

Joined: 23 Jun 2004
Posts: 4

I am writing my first custom node for WBIMB V5 and am close, but missing something... Basically the node is going to compress or uncompress a BLOB and put the result back into the output message BLOB field. (Have to do a custom node since the compression we use is a 3rd party tool we bought sometime ago and runs on our mainframe.)

I have the node up and running except when I dump the output message to a queue no data is passed. I create a new message from the context of the incoming message (which was a BLOB), I do NOT copy the incomming BLOB element, but everything else (i.e. Properties and MQMD). On the new output message I create a BLOB element of type CCI_ELEMENT_TYPE_NAME, and then create a child element under that element named BLOB of type CCI_ELEMENT_TYPE_NAME_VALUE. I then added the uncompress (or compressed) data using the cniSetElementByteArrayValue function to that node.

If I put a trace node right after my node and dump ${Root} I see my BLOB.BLOB data and it looks good.. However when I send that through an MQOutput node the data length is 0 and obviously no data is in the queue. I suspect I am missing something about the parser, but not sure...

Can someone help in telling me what I am missing?

Thanks,
Andy
Back to top
View user's profile Send private message
malammik
PostPosted: Tue May 10, 2005 3:06 pm    Post subject: Reply with quote

Partisan

Joined: 27 Jan 2005
Posts: 397
Location: Philadelphia, PA

You are obviously using C API but I wanted to make sure you know about the following bug which I uncovered in Java api, it is quite possible that it is in c api as well. API libraries fail to convert an element to bit stream if the element does not have the Root as its parent. For example:

SomeElement se = Root.getChild().getChild();

se.toBitStream() returns null. However Root.toBitSteam() does return a valid byte array. After writing custom nodes I usually spend 30 minutes just placing debug statements everywhere including those for printing pointer address values. I suggest you do the same. Good Luck.
_________________
Mikhail Malamud
http://www.netflexity.com
http://groups.google.com/group/qflex
Back to top
View user's profile Send private message Visit poster's website AIM Address
jefflowrey
PostPosted: Tue May 10, 2005 3:55 pm    Post subject: Reply with quote

Grand Poobah

Joined: 16 Oct 2002
Posts: 19981

I'm not positive you've encountered a bug, malammik - unless IBM has confirmed it.

I'd be more suspicious that the problem with heyandy's code is that the Output message doesn't actually have the BLOB parser attached.

You say you aren't copying "the incoming BLOB element" - is that InputRoot.BLOB, or InputRoot.BLOB.BLOB that you aren't copying? If it's the former, then I suspect that is the problem.

If you're creating OutputRoot.BLOB, then you need to do something to attach the BLOB parser to it - and I only know how to do that using ESQL.

If it is the later... then... ummm...

Does the file trace of your output message have exactly the same numbers for the types of the elements as a "proper" blob message?

You might also consider having your node populate fields in Environment or LocalEnvironment, and use ESQL to put them in the right places in the Output tree.
_________________
I am *not* the model of the modern major general.
Back to top
View user's profile Send private message
fschofer
PostPosted: Wed May 11, 2005 12:03 am    Post subject: Reply with quote

Knight

Joined: 02 Jul 2001
Posts: 524
Location: Mainz, Germany

Hi,

i think the unzip plugin does a similar thing.
Maybe it helps to take a look at its source code

http://www-1.ibm.com/support/docview.wss?rs=171&uid=swg24007617&loc=en_US&cs=utf-8&lang=en

Quote:

/* Get the root element of the output message */
outRootElement = cniRootElement(&rc, outMsg);
checkRC(rc);

/* Copy the contents of the input message to the output message */
if (BlobCopy == FALSE)
cniCopyElementTreeWithoutBLOB(&rc, rootElement, outRootElement);
else
cniCopyElementTree(&rc, rootElement, outRootElement);

checkRC(rc);

bodyChild = cniCreateElementAsLastChild(&rc, outRootElement);
checkRC(rc);
cniSetElementType(&rc, bodyChild, CCI_ELEMENT_TYPE_NAME);
checkRC(rc);
cniSetElementName(&rc, bodyChild, (CciChar *)constUNZIP);
checkRC(rc);

//Create Blob Structure
Blob = (struct CciByteArray *)malloc(sizeof(struct CciByteArray));
Blob->pointer = (char *)malloc(sizeof(char) * 10240);
Blob->size = 10240;

blobSize = cniElementByteArrayValue(&rc, blobElement, Blob);
#ifdef _DEBUG
fprintf(outputFile, "%d = cniElementByteArrayValue rc = %d\n", blobSize, rc);
fflush(outputFile);
#endif

if (rc == CCI_BUFFER_TOO_SMALL) {


Greetings
Frank
Back to top
View user's profile Send private message Send e-mail
heyandy
PostPosted: Wed May 11, 2005 4:55 am    Post subject: Further information... Reply with quote

Newbie

Joined: 23 Jun 2004
Posts: 4

Yes I am using the C API (trust me would prefer to use Java, but Java is a 4 letter word around here)...

Anyway, to Jeff's question, I am not copying anything under InputRoot.BLOB... And I was curious about that... I have a trace node just before my node that dumps ${Root} and I get this snippet of the tree:

(0x01000000):BLOB = (
(0x03000000):UnknownParserName = ''
(0x03000000):BLOB =

I put a trace node after my node and dump ${Root} and get the following:

(0x01000000):BLOB = (
(0x03000000):BLOB =

So I wonder if it is just as simple as attaching a CCI_ELEMENT_TYPE_NAME_VALUE node under the first BLOB named "UnknownParserName"? Guess I will go give it a shot and let anyone interested in this topic know...

As to the unzip plugin, that is the sample I gutted to do my node.. However that node does not setup the output tree to be directly sent to a MQOutput node, as you can see by the code they add a "UnZip" branch to the OutputRoot tree that you would then have to manipulate in ESQL afterwards. Since the Compress node I am writing will generally be the last thing done before going to a MQOutput node I am trying to avoid developers having to insert a Compute node after my custom node to save time (we run in the 20 to 30 transactions a second on one server, so performance is always critical.)

Andy
Back to top
View user's profile Send private message
jefflowrey
PostPosted: Wed May 11, 2005 4:59 am    Post subject: Re: Further information... Reply with quote

Grand Poobah

Joined: 16 Oct 2002
Posts: 19981

heyandy wrote:
So I wonder if it is just as simple as attaching a CCI_ELEMENT_TYPE_NAME_VALUE node under the first BLOB named "UnknownParserName"? Guess I will go give it a shot and let anyone interested in this topic know...


I'd be surprised if that worked.

Again, I'd try copying InputRoot.BLOB.BLOB, and then replacing it.
_________________
I am *not* the model of the modern major general.
Back to top
View user's profile Send private message
heyandy
PostPosted: Wed May 11, 2005 6:43 am    Post subject: Got it working... Reply with quote

Newbie

Joined: 23 Jun 2004
Posts: 4

My first thought did not work, so I did take Jeff's suggestion which is I just copied the entire InputRoot to the OutputRoot and then just replaced the BLOB.BLOB field with the new data.

My concern with that is now I am copying the entire message (which could be as high as 256K bytes) just to replace it with another data stream. Again this flow will be in a high volume application and any extra time is a concern.

So my question, is there a way to associate the correct parser to a newly created output message short of copying the original message?

Thanks again,
Andy
Back to top
View user's profile Send private message
jefflowrey
PostPosted: Wed May 11, 2005 7:05 am    Post subject: Reply with quote

Grand Poobah

Joined: 16 Oct 2002
Posts: 19981

It looks like you want cniCreateElementAfterUsingParser
_________________
I am *not* the model of the modern major general.
Back to top
View user's profile Send private message
jhosie
PostPosted: Thu May 12, 2005 1:15 am    Post subject: cniCreateElementAfterUsingParser Reply with quote

Apprentice

Joined: 12 May 2005
Posts: 28

Assuming that you created the BLOB element using one of the following calls
cniCreateElementAfter
cniCreateElementAsLastChild

I agree with jefflowrey, you should use one of the following functions:
cniCreateElementAsLastChildUsingParser or cniCreateElementAfterUsingParser

http://publib.boulder.ibm.com/infocenter/wbihelp/index.jsp?topic=/com.ibm.etools.mft.doc/as07810_.htm
http://publib.boulder.ibm.com/infocenter/wbihelp/index.jsp?topic=/com.ibm.etools.mft.doc/as07870_.htm

and you should specify "NONE" for the parserClassName
http://publib.boulder.ibm.com/infocenter/wbihelp/index.jsp?topic=/com.ibm.etools.mft.doc/as07410_.htm

The thinking behind this is, when you create an element using e.g. cniCreateElementAsLastChild or cniCreateElementAfter, then that element belongs to the same parser as its parent. Probably the Root parser in this case.

So when the MQOutputNode asks the parsers for their bitstreams, to put onto the queue, he only gets the MQMD bitstream. This is because the rest of the tree, including the BLOB element that you created is owned by either the Properties parser or the Root parser. Neither of which can produce any bitstream.

I am assuming that you created the BLOB element by using one of the following calls
cniCreateElementAfter
cniCreateElementAsLastChild

Most people coming from ESQL make this mistake.
When you do the following in ESQL
SET OutputRoot.BLOB.BLOB = mydata;
ESQL is kind enough to notice that you have created an element, as a direct child of the root element and you named it BLOB so you must have intended for it to be in the BLOB domain, so ESQL assigns it to the BLOB parser. The C plug-in API does not make this choice for you. You need to assign it to the BLOB parser yourself.
Back to top
View user's profile Send private message
heyandy
PostPosted: Fri May 13, 2005 9:37 am    Post subject: Thanks! Reply with quote

Newbie

Joined: 23 Jun 2004
Posts: 4

That was indeed my problem, since I was not associating a parser to the element no output was being done. I am now using the CniCreateElementAsLastChildUsingParser function and no longer copying the entire input message and everything works as expected...

Thanks again everyone for your help.

Andy
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 » Custom WBIMB Node question
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.