|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
JavaCompute : Earlier message propagated |
« View previous topic :: View next topic » |
Author |
Message
|
Cogito-Ergo-Sum |
Posted: Sat Feb 26, 2011 6:30 am Post subject: JavaCompute : Earlier message propagated |
|
|
 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 |
|
 |
mqjeff |
Posted: Sat Feb 26, 2011 7:37 am Post subject: |
|
|
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 |
|
 |
Cogito-Ergo-Sum |
Posted: Sat Feb 26, 2011 8:34 am Post subject: |
|
|
 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 |
|
 |
rekarm01 |
Posted: Sat Feb 26, 2011 8:43 pm Post subject: Re: JavaCompute: Earlier message propagated |
|
|
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 |
|
 |
Cogito-Ergo-Sum |
Posted: Sun Feb 27, 2011 1:29 am Post subject: |
|
|
 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 |
|
 |
|
|
 |
|
Page 1 of 1 |
|
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
|
|
|
|