Within a message processing or output node, you can add extended functions.
Before you start
Read and understood Creating a message processing or output node in Java .
Nodes can invoke ESQL expressions using Compute node ESQL syntax. You can create and modify the components of the message using ESQL expressions, and you can refer to elements of both the input message and data from an external database.
String dataSourceName = "myDataSource";
String statement = "SET OutputRoot.XMLNS.data = (SELECT Field2 FROM Database.Table1 WHERE Field1 = 1);";
String statement = "PASSTHRU( 'INSERT INTO Database.Table1 VALUES( InputRoot.XMLNS.DataField1, InputRoot.XMLNS.DataField2)');";
int transactionType = MbSQLStatement.SQL_TRANSACTION_AUTO;
MbSQLStatement sql = createSQLStatement(dataSourceName, statement, transactionType);You can use the method createSQLStatement(dataSource, statement to default the transaction type to MbSQLStatement.SQL_TRANSACTION_AUTO).
MbMessageAssembly newAssembly = new MbMessageAssembly(assembly, assembly.getMessage());
sql.select(assembly, newAssembly);
sql.execute(assembly);
For more information about ESQL, see ESQL overview.
You use the MbException class to catch and access exceptions. The MbException class returns an array of exception objects representing the children of an exception in the broker exception list. Each element returned specifies its exception type. An empty array is returned if an exception has no children. The following code sample shows an example of how the MbException class could be used in the evaluate method of your user-defined node.
public void evaluate(MbMessageAssembly assembly, MbInputTerminal inTerm) throws MbException { try { // plug-in functionality } catch(MbException ex) { traverse(ex, 0); throw ex; // if re-throwing, it must be the original exception that was caught } } void traverse(MbException ex, int level) { if(ex != null) { // Do whatever action here System.out.println("Level: " + level); System.out.println(ex.toString()); System.out.println("traceText: " + ex.getTraceText()); // traverse the hierarchy MbException e[] = ex.getNestedExceptions(); int size = e.length; for(int i = 0; i < size; i++) { traverse(e[i], level + 1); } } }
Refer to the Java API for more details of using the MbException class.
You can develop a user-defined message processing or output node in such a way that it can access all current exceptions. For example, to catch database exceptions you can use the MbSQLStatement class. This class sets the value of the 'throwExceptionOnDatabaseError' attribute, which determines broker behavior when it encounters a database error. When it is set to true, if an exception is thrown, it can be caught and handled by the evaluate method in your user-defined extension.
The following code sample shows an example of how to use the MbSQLStatement class.
public void evaluate(MbMessageAssembly assembly, MbInputTerminal inTerm) throws MbException { MbMessage newMsg = new MbMessage(assembly.getMessage()); MbMessageAssembly newAssembly = new MbMessageAssembly(assembly, newMsg); String table = assembly.getMessage().getRootElement().getLastChild().getFirstChild().getName(); MbSQLStatement state = createSQLStatement( "dbName", "SET OutputRoot.XMLNS.integer[] = PASSTHRU('SELECT * FROM " + table + "');" ); state.setThrowExceptionOnDatabaseError(false); state.setTreatWarningsAsErrors(true); state.select( assembly, newAssembly ); int sqlCode = state.getSQLCode(); if(sqlCode != 0) { // Do error handling here System.out.println("sqlCode = " + sqlCode); System.out.println("sqlNativeError = " + state.getSQLNativeError()); System.out.println("sqlState = " + state.getSQLState()); System.out.println("sqlErrorText = " + state.getSQLErrorText()); } getOutputTerminal("out").propagate(newAssembly); }
To write to an output device, the logical (hierarchical) message must be converted back into a bit stream in your evaluate method. Use the getBuffer method in MbMessage to perform thsi task, as follows:
public void evaluate( MbMessageAssembly assembly, MbInputTerminal in) throws MbException { MbMessage msg = assembly.getMessage(); byte[] bitstream = msg.getBuffer(); // write the bitstream out somewhere writeBitstream( bitstream ); // user method }
Typically, for an output node the message is not propagated to any output terminal, so you can just return at this point.
You must use the supplied MQOutput node when writing to WebSphere MQ queues, because the broker internally maintains a WebSphere MQ connection and open queue handles on a thread-by-thread basis, and these handles are cached to optimize performance. In addition, the broker handles recovery scenarios when certain WebSphere MQ events occur, and this would be adversely affected if WebSphere MQ MQI calls were used in a user-defined output node.