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 » JavaCompute : Earlier message propagated

Post new topic  Reply to topic
 JavaCompute : Earlier message propagated « View previous topic :: View next topic » 
Author Message
Cogito-Ergo-Sum
PostPosted: Sat Feb 26, 2011 6:30 am    Post subject: JavaCompute : Earlier message propagated Reply with quote

Master

Joined: 07 Feb 2006
Posts: 293
Location: Bengaluru, India

Hello !
In an issue similar to one posted here, I am required to write out XML as messages into output queue using a JavaCompute node. I am unable to arrive at a solution other than using detach() method which I am not sure is the right way.

Help !

The XML is simply the following. The <tag> element can occur >= 1 times.
Code:
<root><tag>data</tag></root


Using finalizeMessage(MbMessage.FINALIZE_NONE) outside the for loop:
Code:

   public void evaluate(MbMessageAssembly contact admin) throws MbException {
      //Set-up
      MbOutputTerminal out = getOutputTerminal("out");
      MbMessage inMessage = contact admin.getMessage();
      MbMessage outMessage = new MbMessage();
      MbMessageAssembly outAssembly = new MbMessageAssembly(contact admin,outMessage);
      copyMessageHeaders(inMessage,outMessage);
      
      MbElement outRoot = outMessage.getRootElement();
      MbElement outParser = outRoot.createElementAsLastChild(MbXMLNSC.PARSER_NAME);
      MbElement xmlRoot = outParser.createElementAsLastChild(MbXMLNSC.FIELD, "root", null);
      MbElement xmlBody ;
      
      String[] dataArray1 = {"A", "B", "C"} ;
      for (int i=0; i<dataArray1.length; i++) {
         xmlBody = xmlRoot.createElementAsLastChild(MbXMLNSC.FIELD,"tag",dataArray1[i]);
      }
      outMessage.finalizeMessage(MbMessage.FINALIZE_NONE);
      out.propagate(outAssembly);

      outRoot = outMessage.getRootElement();
      outParser = outRoot.createElementAsLastChild(MbXMLNSC.PARSER_NAME);
      xmlRoot = outParser.createElementAsLastChild(MbXMLNSC.FIELD, "root", null);
      
      String dataArray2[] = {"P","Q","R","S","T"} ;
      for (int i=0; i<dataArray2.length; i++) {
         xmlBody = xmlRoot.createElementAsLastChild(MbXMLNSC.FIELD,"tag",dataArray2[i]);
      }
      outMessage.finalizeMessage(MbMessage.FINALIZE_NONE);
      out.propagate(outAssembly);
      
   }

Result:
Code:

<root><tag>A</tag><tag>B</tag><tag>C</tag></root>
<root><tag>A</tag><tag>B</tag><tag>C</tag></root><root><tag>P</tag><tag>Q</tag><tag>R</tag><tag>S</tag><tag>T</tag></root>

Using finalizeMessage(MbMessage.FINALIZE_NONE) within the for loop:
Code:

   public void evaluate(MbMessageAssembly contact admin) throws MbException {
      //Set-up
      MbOutputTerminal out = getOutputTerminal("out");
      MbMessage inMessage = contact admin.getMessage();
      MbMessage outMessage = new MbMessage();
      MbMessageAssembly outAssembly = new MbMessageAssembly(contact admin,outMessage);
      copyMessageHeaders(inMessage,outMessage);
      
      MbElement outRoot = outMessage.getRootElement();
      MbElement outParser = outRoot.createElementAsLastChild(MbXMLNSC.PARSER_NAME);
      MbElement xmlRoot = outParser.createElementAsLastChild(MbXMLNSC.FIELD, "root", null);
      MbElement xmlBody ;
      
      String[] dataArray1 = {"A", "B", "C"} ;
      for (int i=0; i<dataArray1.length; i++) {
         xmlBody = xmlRoot.createElementAsLastChild(MbXMLNSC.FIELD,"tag",dataArray1[i]);
         outMessage.finalizeMessage(MbMessage.FINALIZE_NONE);
      }
      out.propagate(outAssembly);

      outRoot = outMessage.getRootElement();
      outParser = outRoot.createElementAsLastChild(MbXMLNSC.PARSER_NAME);
      xmlRoot = outParser.createElementAsLastChild(MbXMLNSC.FIELD, "root", null);
      
      String dataArray2[] = {"P","Q","R","S","T"} ;
      for (int i=0; i<dataArray2.length; i++) {
         xmlBody = xmlRoot.createElementAsLastChild(MbXMLNSC.FIELD,"tag",dataArray2[i]);
         outMessage.finalizeMessage(MbMessage.FINALIZE_NONE);
      }
      out.propagate(outAssembly);
      
   }

Result:
Code:

<root><tag>A</tag><tag>B</tag><tag>C</tag></root>
<root><tag>A</tag><tag>B</tag><tag>C</tag></root><root><tag>P</tag><tag>Q</tag><tag>R</tag><tag>S</tag><tag>T</tag></root>


As per the documentation (emphasis mine) for Generating multiple output messages, the propagate method should 'nullify' the buffer and be ready for next propagation. That is why, I am redefining the outRoot, outParser and xmlRoot before next propagation. But, the results do not match with the documentation.
Quote:
In the above example, the content of OutputRoot is reset before each PROPAGATE, because by default the node clears the output message buffer and reclaims the memory when the PROPAGATE statement completes.


So, how about forcing the clearing the message using outMessage.clearMessage() between the propagate statements ? That causes a neat exception as documented in the javadoc.

Therefore, I am forced to navigate to the root of the sub-tree (<root>) owned by parser and keep detaching all children (<tag>) using detach() method somewhat like this.
Code:

   public void detachBody(MbElement r) throws MbException {
      MbElement body = r.getFirstChild();
      while (body != null) {
         body.detach();
         body = r.getFirstChild();
      }
   }

This does the job, but if the number of <tag> elements go up - I doubt, they will go beyond 10 - or, they are required to carry multiple attributes, then there are too many to detach. And, well, I am not sure, if attaching element/attribute by element/attribute and then detaching them one by one is a good idea.

_________________
ALL opinions are welcome.
-----------------------------
Debugging tip:When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.
---Sherlock Holmes
Back to top
View user's profile Send private message
mqjeff
PostPosted: Sat Feb 26, 2011 7:37 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

Code appears to be working as designed.

You create a message tree, and populate it.

You then use the same message tree, and create a new message tree at the bottom of it.

You can either reuse the message elements that already exist, by using setValue() and setName(), or you can create a new MbMessage.

Make sure to clearMessage() on the old one.
Back to top
View user's profile Send private message
Cogito-Ergo-Sum
PostPosted: Sat Feb 26, 2011 8:34 am    Post subject: Reply with quote

Master

Joined: 07 Feb 2006
Posts: 293
Location: Bengaluru, India

Quote:
You then use the same message tree, and create a new message tree at the bottom of it.

So, the propagate() method does not 'nullify' the buffer ?

As mentioned by you, I used a new MbMessage and got it working this way.
Code:

   public void evaluate(MbMessageAssembly contact admin) throws MbException {
      //Set-up
      MbOutputTerminal out = getOutputTerminal("out");
      MbMessage inMessage = contact admin.getMessage();
      MbMessage outMessage = new MbMessage();
      MbMessageAssembly outAssembly = new MbMessageAssembly(contact admin,outMessage);
      copyMessageHeaders(inMessage,outMessage);
      
      MbElement outRoot = outMessage.getRootElement();
      MbElement outParser = outRoot.createElementAsLastChild(MbXMLNSC.PARSER_NAME);
      MbElement xmlRoot = outParser.createElementAsLastChild(MbXMLNSC.FIELD, "root", null);
      MbElement xmlBody ;
      
      String[] dataArray1 = {"A", "B", "C"} ;
      for (int i=0; i<dataArray1.length; i++) {
         xmlBody = xmlRoot.createElementAsLastChild(MbXMLNSC.FIELD,"tag",dataArray1[i]);
         outMessage.finalizeMessage(MbMessage.FINALIZE_NONE);
      }
      out.propagate(outAssembly);
      outMessage.clearMessage();
      
      outMessage = new MbMessage();
      outAssembly = new MbMessageAssembly(contact admin,outMessage);
      copyMessageHeaders(inMessage,outMessage);
      outRoot = outMessage.getRootElement();
      outParser = outRoot.createElementAsLastChild(MbXMLNSC.PARSER_NAME);
      xmlRoot = outParser.createElementAsLastChild(MbXMLNSC.FIELD, "root", null);
      
      String dataArray2[] = {"P","Q","R","S","T"} ;
      for (int i=0; i<dataArray2.length; i++) {
         xmlBody = xmlRoot.createElementAsLastChild(MbXMLNSC.FIELD,"tag",dataArray2[i]);
         outMessage.finalizeMessage(MbMessage.FINALIZE_NONE);
      }
      out.propagate(outAssembly);
      
   }


Thank you !
_________________
ALL opinions are welcome.
-----------------------------
Debugging tip:When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.
---Sherlock Holmes
Back to top
View user's profile Send private message
rekarm01
PostPosted: Sat Feb 26, 2011 8:43 pm    Post subject: Re: JavaCompute: Earlier message propagated Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 1415

A compute node should generally observe the following sequence of steps when handling an output message:

    create -> modify -> finalize -> propagate -> delete

Some of the steps may be optional or repeatable, but they should occur in the order given.

Cogito-Ergo-Sum wrote:
So, the propagate() method does not 'nullify' the buffer?

No. The MbMessage.propagate() method is not the ESQL PROPAGATE statement. ESQL Compute nodes finalize and delete the output message by default, when propagating it. JavaCompute nodes don't.

For a JavaCompute node:
  • Do not modify an output message after calling finalizeMessage().
  • For every new MbMessage instantiated, always call clearMessage() to delete it; use try/finally blocks to make sure that happens.
  • Do not modify, finalize, or propagate an output message after calling clearMessage().
In the given example, call clearMessage() for both the "ABC" and the "PQRST" MbMessages.

Optionally: declare unmodified variables as "final", and eliminate unnecessary variables, to help avoid programming errors, and to optimize the resulting code; refactor, to reduce duplicate code.

Code:
public void evaluate(MbMessageAssembly contact admin) throws MbException {
   final MbOutputTerminal out = getOutputTerminal("out");
   final MbMessage inMessage = contact admin.getMessage();
   MbMessage outMessage;

   final String dataArray[][] = {
      {"A", "B", "C"},
      {"P", "Q", "R", "S", "T"}
   };

   for (int i = 0; i < dataArray.length; i++)
   {
      outMessage = null;
      try
      {
         outMessage = new MbMessage();
         final MbMessageAssembly outAssembly = new MbMessageAssembly(contact admin, outMessage);
         copyMessageHeaders(inMessage, outMessage);

         final MbElement xmlRoot = outMessage.getRootElement()
            .createElementAsLastChild(MbXMLNSC.PARSER_NAME)
            .createElementAsLastChild(MbXMLNSC.FIELD, "root", null);

         for (int j = 0; j < dataArray[i].length; j++) {
            xmlRoot.createElementAsLastChild(MbXMLNSC.FIELD, "tag", dataArray[i][j]);
         }
         outMessage.finalizeMessage(MbMessage.FINALIZE_NONE);
         out.propagate(outAssembly);
      }
      finally
      {
         if (outMessage != null)
            outMessage.clearMessage();
      }
   }
}
Back to top
View user's profile Send private message
Cogito-Ergo-Sum
PostPosted: Sun Feb 27, 2011 1:29 am    Post subject: Reply with quote

Master

Joined: 07 Feb 2006
Posts: 293
Location: Bengaluru, India

Quote:
No. The MbMessage.propagate() method is not the ESQL PROPAGATE statement. ESQL Compute nodes finalize and delete the output message by default, when propagating it. JavaCompute nodes don't.


Thanks !
_________________
ALL opinions are welcome.
-----------------------------
Debugging tip:When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.
---Sherlock Holmes
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 » JavaCompute : Earlier message propagated
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.