...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
var jobChainPath = null; var jobChainNodeState = null; var orderExpectedValue = null; var orderExpectedDefaultValue = null; var orderExpectedValueFunction = "parseInt(currentValue) + 1"; var controlOrderPrefix = "control_order_"; var controlOrderID = null; function executeXML( command ) { var rc = false; spooler_log.debug( ".... executing xml command: " + command ); var response = spooler.execute_xml( command ); var xmlDOM = new Packages.sos.xml.SOSXMLXPath( new java.lang.StringBuffer( response ) ); var errorCode = xmlDOM.selectSingleNodeValue( "//ERROR/@code" ); var errorText = xmlDOM.selectSingleNodeValue( "//ERROR/@text" ); if ( errorCode || errorText ) { spooler_log.error( ".... xml response: errorCode=" + errorCode + ", errorText=" + errorText ); } else { rc = xmlDOM; } return rc; } function getOrderExpectedValue() { if (orderExpectedValue == null) { orderDOM = executeXML( "<show_order job_chain='" + jobChainPath + "' order='" + controlOrderID + "' what='payload'/>" ); if ( orderDOM ) { orderExpectedValue = orderDOM.selectSingleNodeValue( "/spooler/answer/order/payload/params/param[@name = '" + controlOrderID + "']/@value" ); } } if ( !orderExpectedValue ) { orderExpectedValue = orderExpectedDefaultValue; spooler_log.info( ".... getOrderExpectedValue(): " + orderExpectedValue + " (default)" ); } else { spooler_log.info( ".... getOrderExpectedValue(): " + orderExpectedValue ); } return orderExpectedValue; } function setOrderExpectedValue( expectedValue ) { spooler_log.info( ".... setOrderExpectedValue(): " + expectedValue ); var rc = true; orderExpectedValue = expectedValue; // check existence of control order, if historic then its state does not match the job node state var orderDOM = executeXML( "<show_order job_chain='" + jobChainPath + "' order='" + controlOrderID + "' what='payload'/>" ); if ( orderDOM ) { var orderState = orderDOM.selectSingleNodeValue( "/spooler/answer/order/@state" ); if (!orderState || orderState != jobChainNodeState) { rc = false; } } else { rc = false; } // add or modify control order if (!rc) { orderDOM = executeXML( "<add_order job_chain='" + jobChainPath + "' id='" + controlOrderID + "' state='" + jobChainNodeState + "' suspended='yes'><params><param name='" + controlOrderID + "' value='" + orderExpectedValue + "'/></params><run_time/></add_order>" ); } else { orderDOM = executeXML( "<modify_order job_chain='" + jobChainPath + "' order='" + controlOrderID + "' state='" + jobChainNodeState + "' suspended='yes'><params><param name='" + controlOrderID + "' value='" + orderExpectedValue + "'/></params><run_time/></modify_order>" ); } spooler_job.state_text = "next expected value: " + orderExpectedValue; } function calculateOrderExpectedValue( currentValue ) { // calculate next date for a date parameter // var expectedValue = (new Date( (new Date(currentValue)).setDate( (new Date(currentValue)).getDate()+1 ) )).toISOString().substring(0,10); // calculate increment for a numeric parameter or order id // var expectedValue = parseInt(currentValue) + 1; var expectedValue = eval( orderExpectedValueFunction ); return expectedValue; } function spooler_init() { jobChainPath = spooler_task.order.job_chain.path; jobChainNodeState = spooler_task.order.job_chain_node.state; controlOrderID = controlOrderPrefix + spooler_task.order.job_chain_node.state; return true; } function spooler_process() { var rc = true; // control order is always suspended if (spooler_task.order.id == controlOrderID) { spooler_log.info( ".. control order identified, processing suspended" ); suspendOrder(); return rc; } // merge parameters from task and order var params = spooler.create_variable_set(); params.merge( spooler_task.params ); params.merge( spooler_task.order.params ); // get expected value from a parameter name or from the Order ID spooler_log.info( ".. control parameter for expected value is looked up: " + controlOrderPrefix + "expected_parameter" ); var expectedParameter = params.value( controlOrderPrefix + "expected_parameter" ); if (expectedParameter) { var currentValue = params.value( expectedParameter ); spooler_log.info( ".. current value is used from control parameter [" + expectedParameter + "]: " + currentValue ); } else { var currentValue = spooler_task.order.id; spooler_log.info( ".. current value is used from order id: " + currentValue ); } // get expected default value from a parameter or from the order id if (!orderExpectedDefaultValue) { orderExpectedDefaultValue = params.value( controlOrderPrefix + "expected_default_value" ); if (orderExpectedDefaultValue) { spooler_log.info( ".. default value is used from control parameter [" + controlOrderPrefix + "expected_default_value]: " + orderExpectedDefaultValue ); } else { spooler_log.info( ".. default value is used from order id: " + spooler_task.order.id ); orderExpectedDefaultValue = spooler_task.order.id; } } // get expected value calculation function var expectedValueFunction = params.value( controlOrderPrefix + "expected_value_function" ); if (expectedValueFunction) { orderExpectedValueFunction = expectedValueFunction; spooler_log.info( ".. using expected value function: " + orderExpectedValueFunction ); } else { spooler_log.info( ".. using expected value default function: " + orderExpectedValueFunction ); } // check if order value matches expectation if ( getOrderExpectedValue() == currentValue ) { // after processing of the current order all suspended orders are activated spooler_log.info( ".. current order provides expected value: " + getOrderExpectedValue() ); activateSuspendedOrders(); setOrderExpectedValue( calculateOrderExpectedValue( getOrderExpectedValue() ) ); } else { // suspend non-matching order spooler_log.info( ".. suspending current order: expected value=" + getOrderExpectedValue() + ", current value=" + currentValue ); suspendOrder(); } return rc; } function suspendOrder() { spooler_task.order.suspended = true; spooler_task.order.state = jobChainNodeState; } function activateSuspendedOrders() { var rc = true; var orderList = Array(); // select suspended orders of the current job node var orderDOM = executeXML( "<show_job_chain job_chain='" + jobChainPath + "' what='job_chain_orders'/>" ); var orderNodes = orderDOM.selectNodeList( "/spooler/answer/job_chain/job_chain_node[@state = '" + jobChainNodeState + "']/order_queue/order[@suspended = 'yes']" ); // traverse order list and add orders to sort array for( orderIndex=0; orderIndex<orderNodes.getLength(); orderIndex++ ) { var orderNode = orderNodes.item(orderIndex); var orderID = orderDOM.selectSingleNodeValue( orderNode, "@id" ); if (orderID == null || controlOrderID) { continue; } spooler_log.info( ".... suspended order found: " + orderID ); orderList.push( orderID ); } // alphabetical string sort orderList.sort(function(a, b){return (a > b) - (a < b) }); // numeric sort // orderList.sort(function(a, b){return b - a) }); for(i=0; i<orderList.length; i++) { spooler_log.info( ".... activating order: " + orderList[i] ); orderDOM = executeXML( "<modify_order job_chain='" + jobChainPath + "' order='" + orderList[i] + "' state='" + jobChainNodeState + "' suspended='no'/>" ); if ( !orderDOM ) { rc = false; } } return rc; } |
Usage
- Add two thre orders to the
job_chain_expect_orders
job chain.- Use an order id in descending alphabetical order, e.g. "cba" for the order id of the first order and "abc" for the order id of the second order.
- Both orders will be suspended in the first node of the job chain.
- After an idle timeout of 10s both orders are moved to the next job node in the job chain.
- This time the orders are processed in ascending alphabetical order
- . For your convenience the orders 1, 2 and 3 are provided with the sample.
- Each order uses a parameter
sequence
with a sequential number such as 1, 2, 3. - The
expect
job uses the parameterscontrol_order_expected_parameter
with the value:sequence
control_order_expected_default_value
with the value:1
control_order_expected_value_function
with the value:parseInt(currentValue) + 1
- Each order uses a parameter
- Start order 1 that matches the expected value (parameter
sequence=1
).- The order is processed and moved to the
next_job
job. - A control order
control_order_expect
is dynamically created and suspended that contains the next expected value (parametercontrol_order_expect=2
)
- The order is processed and moved to the
- Start order 3 that does not match the expected value (parameter
sequence=3
).- The order is suspended.
- The control order with the expected value (parameter
control_order_expect=2
) remains unchanged.
- Start order 2 that does match the expected value (parameter
sequence=2
) .- Order 2 is processed and moved to the
next_job
job.- The control order is automatically modified to carry the next expected value (parameter
control_order_expect=3
).
- The control order is automatically modified to carry the next expected value (parameter
- Order 3 is processed and moved to the
next_job
job.- The control order is automatically modified to carry the next expected value (parameter
control_order_expect=4
).
- The control order is automatically modified to carry the next expected value (parameter
- Order 2 is processed and moved to the
.