|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
Executing compiled WTX map retrieved from WSRR in WMB |
« View previous topic :: View next topic » |
Author |
Message
|
billybong |
Posted: Thu Sep 11, 2008 4:46 am Post subject: Executing compiled WTX map retrieved from WSRR in WMB |
|
|
 Disciple
Joined: 22 Jul 2005 Posts: 150 Location: Stockholm, Sweden
|
Hi!
I have a scenario where I'd like to retreive a compiled WTX map from the WSRR and then use that map to transform an incoming message.
When the registrylookup node retreives the map its interpreted as a char under LocalEnvironment.ServiceRegistry.Entity.content which causes me trouble since the WTX maps are compiled byte-files. I've tried to use the WTX node to no avail so I'm instead resorting to the WTX Java API in a compute node to actually run the map.
The problem is that the constructor for creating a MMap object only accepts byte[] and I'm a bit rusty in how to interpret the char-encoded data that I got from WSRR. I get an exception at the line:
MMap map = new MMap("genericMap", null, mapData);
Source code for the JCN TransformUsingWTX below, bear in mind that this is a first test and I'll have to think about whether to use a static class or not later on:
Code: |
public class TransformUsingWSRRtxMap_TransformUsingWtxMap extends
MbJavaComputeNode {
public void evaluate(MbMessageAssembly contact admin) throws MbException {
MbOutputTerminal out = getOutputTerminal("out");
MbMessage inMessage = contact admin.getMessage();
// create new message
MbMessage outMessage = new MbMessage();
// copy the message headers
copyMessageHeaders(inMessage, outMessage);
MbMessageAssembly outAssembly = new MbMessageAssembly(contact admin,
outMessage);
try {
// ----------------------------------------------------------
// Add user code below
byte[] mapData;
byte[] inputData;
inputData = (byte[])inMessage.getRootElement().getValue();
MbElement localEnv = contact admin.getLocalEnvironment().getRootElement();
MbElement wsrrContent = (MbElement)localEnv.getFirstElementByPath("/ServiceRegistry/Entity/content");
String mapContent = (String)wsrrContent.getValue();
mapData = (byte[])mapContent.getBytes();
outMessage.getRootElement().setValue(TxTransformer.transform(inputData, mapData));
// End of user code
// ----------------------------------------------------------
// The following should only be changed
// if not propagating message to the 'out' terminal
out.propagate(outAssembly);
} catch (MException e) {
e.fillInStackTrace();
}
finally {
// clear the outMessage
outMessage.clearMessage();
}
}
public void copyMessageHeaders(MbMessage inMessage, MbMessage outMessage) throws MbException
{
MbElement outRoot = outMessage.getRootElement();
MbElement header = inMessage.getRootElement().getFirstChild();
while(header != null && header.getNextSibling() != null)
{
outRoot.addAsLastChild(header.copy());
header = header.getNextSibling();
}
}
}
class TxTransformer{
public static byte[] transform(byte[] inputData, byte[] mapData) throws MException{
// Initialize the API
MMap.initializeAPI(null);
// Create a map
MMap map = new MMap("genericMap", null, mapData);
// Override the input card so that a local file
// containing input data can be sent to the remote server
MCard card = map.getInputCardObject(1);
card.overrideAdapter(null, MConstants.MPI_ADAPTYPE_STREAM);
// Pass it to the server via a stream
MAdapter adapter = card.getAdapter();
MStream stream = adapter.getOutputStream();
stream.write(inputData, 0, inputData.length);
// Get the adapter object handle for output card #1
card = map.getOutputCardObject(1);
// Override the adapter in output card #1 to be a stream
card.overrideAdapter(null, MConstants.MPI_ADAPTYPE_STREAM);
// Run the map
map.run();
// Check the return status, only used while debugging
int iRC = map.getIntegerProperty(MConstants.MPIP_OBJECT_ERROR_CODE, 0);
String szMsg = map.getTextProperty(MConstants.MPIP_OBJECT_ERROR_MSG, 0);
//Sysout does not work in broker env
//System.out.println("Map status: " + szMsg + " (" + iRC + ")");
// Get the adapter object handle for output card #1
adapter = card.getAdapter();
stream = adapter.getInputStream();
// Get the data in pieces from the stream
stream.seek(0, MConstants.MPI_SEEK_SET);
while( true )
{
boolean bIsEnd = stream.isEnd();
// Clean and Break
if( bIsEnd )
{
stream.setSize(0);
break;
}
}
// Clean up
map.unload();
MMap.terminateAPI();
byte[] page = stream.readPage();
return page;
}
}
|
_________________ IBM Certified Solution Developer - WebSphere Message Broker V6.1
IBM Certified Solution Developer - WebSphere Integration Developer V6.0
IBM Certified System Administrator - WebSphere MQ V6.0
IBM Certified Solution Developer - WebSphere DataPower |
|
Back to top |
|
 |
sridhsri |
Posted: Thu Sep 11, 2008 8:38 pm Post subject: |
|
|
Master
Joined: 19 Jun 2008 Posts: 297
|
Its a novel idea you have there ! This was discussed by my colleagues before and I found the idea very interesting. The WTX node does not support changing the map at run time. So you are left with no choice but to write the APIs.
I haven't used much of these APIs. But I do see that
Quote: |
// Create a map
MMap map = new MMap("genericMap", null, mapData);
|
The second parameter must point to a valid working directory.
Ex:
String str = "c:\"; or
String str = ".";
Second (and I could very well be wrong here), the map must exist in the classpath and is loaded from there. So, I am beginning to wonder if this would work. Try running this as a stand alone java app. I know I haven't been much help - but I would be very interested to know if you succeed with this. |
|
Back to top |
|
 |
sridhsri |
Posted: Thu Sep 11, 2008 8:41 pm Post subject: |
|
|
Master
Joined: 19 Jun 2008 Posts: 297
|
Sorry - I made a mistake. There is no need for maps to be in classpath. As long as you have the map as a byte array you should be good to go. |
|
Back to top |
|
 |
billybong |
Posted: Thu Sep 11, 2008 11:21 pm Post subject: |
|
|
 Disciple
Joined: 22 Jul 2005 Posts: 150 Location: Stockholm, Sweden
|
Thanks for the input sridhsri. I'll have to try sending an existing directory as an argument as you hinted at.
The problem is with the retreival of the compiled map from wsrr, since every content the wsrr nodes return is in char, even though the document is loaded in wsrr as a binary file.
I could presumably go back to using the wsrr api as well since I'm using the WTX api already, but that would mean I miss out on the cache functionality and wont be able to change wsrr settings directly in the broker.
Btw, I know that this solution works since I have an old customer using it in production. We drew the plans for it about an age ago and now they are in production. I wasn't on the project except at the initial design stage, so I'd like to reproduce the scenario. Since its quite sensitive data I'm not so sure theyre willing to share the code with me though. _________________ IBM Certified Solution Developer - WebSphere Message Broker V6.1
IBM Certified Solution Developer - WebSphere Integration Developer V6.0
IBM Certified System Administrator - WebSphere MQ V6.0
IBM Certified Solution Developer - WebSphere DataPower |
|
Back to top |
|
 |
Subha |
Posted: Fri Sep 12, 2008 1:13 am Post subject: |
|
|
Apprentice
Joined: 14 Nov 2006 Posts: 33 Location: Toronto
|
sridhsri wrote: |
The WTX node does not support changing the map at run time. So you are left with no choice but to write the APIs.
|
Actually I tried overwriting map properties during run time and I was successful.
I used this
OutputLocalEnvironment.WTX.MapServerLocation = 'ExecutableMapLocation';
I believe the requirement here is to have maps selected at run time. In that case , you can try setting Map properties using Compute node.
Thanks! _________________ Subh |
|
Back to top |
|
 |
billybong |
Posted: Fri Sep 12, 2008 1:38 am Post subject: |
|
|
 Disciple
Joined: 22 Jul 2005 Posts: 150 Location: Stockholm, Sweden
|
Subha wrote: |
sridhsri wrote: |
The WTX node does not support changing the map at run time. So you are left with no choice but to write the APIs.
|
Actually I tried overwriting map properties during run time and I was successful.
I used this
OutputLocalEnvironment.WTX.MapServerLocation = 'ExecutableMapLocation';
I believe the requirement here is to have maps selected at run time. In that case , you can try setting Map properties using Compute node.
Thanks! |
It's not the problem of setting the map location in runtime. Rather that you cant specify a map from memory, i.e. the LocalEnvironment where wsrr puts its retreived content. _________________ IBM Certified Solution Developer - WebSphere Message Broker V6.1
IBM Certified Solution Developer - WebSphere Integration Developer V6.0
IBM Certified System Administrator - WebSphere MQ V6.0
IBM Certified Solution Developer - WebSphere DataPower |
|
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
|
|
|
|