Script
Purpose¶
Call and list scripts.
Methods¶
Binding name: p6.script
call¶
Execute the named script and waits for it to complete. The current pipeline will be used by the called script.
Syntax
Map<String, TypedContent> p6.script.call(String scriptName)
Example
// Prepare pipeline variables for the sub-script
p6.pipeline.put('customerId', 'CUST-00712')
// Call the invoice generation script and inspect the result
def result = p6.script.call('MyApp.GenerateInvoice')
p6.log.debug 'Script returned ' + result.size() + ' pipeline entries'
start¶
Submits the named script for execution and returns its job id as a String. This method DOES NOT wait for the script execution to complete.
Syntax
String p6.script.start(String scriptName)
Tip
You can use the Platform6 job DSL to interact with the started script job using the returned job id
Example
// Start a long-running report generation script asynchronously
def jobId = p6.script.start('Reporting.MonthlyExport')
p6.log.info 'Started report generation, job ID: ' + jobId
exists¶
Checks if the given script exists.
Syntax
boolean p6.script.exists(String scriptName)
Example
// Guard against calling a script that may not be deployed
if (p6.script.exists('MyApp.ProcessCreditNote')) {
p6.script.call('MyApp.ProcessCreditNote')
} else {
p6.log.warn 'Credit note processing script not found'
}
list¶
Return a collection of all scripts names.
Syntax
List<String> p6.script.list()
Example
// List all scripts belonging to the MyApp application
p6.script.list().findAll { it.startsWith('MyApp.') }.each {
p6.log.debug 'MyApp script: ' + it
}
Best practices: propagating log context across scripts¶
The p6.log.with(key, value) context is bound to the
current script’s p6.log instance. Every script execution receives a
fresh p6.log binding with an empty context map, so entries set in a
calling script (sidetrade.tenant.id, batch.id, operation.id, …) are
not automatically visible to a called or started script, nor to other
threads or other cluster nodes.
If you want those values to follow the work, you must propagate them through an explicit channel and re-apply them on the receiving side.
Across p6.script.call (synchronous, same node)¶
call runs the target script in the same JVM, on the same thread, and the
pipeline is shared with the callee. The simplest pattern is to write
the context entries into the pipeline before the call and to re-apply them
with p6.log.with at the top of the callee.
Caller
// Stash the log context the callee should adopt — one pipeline entry per key
p6.pipeline.put 'log.ctx.sidetrade.tenant.id', '303660'
p6.pipeline.put 'log.ctx.batch.id', String.valueOf(batchId)
p6.pipeline.put 'log.ctx.operation.id', String.valueOf(operationId)
p6.script.call 'MyApp.ProcessBatch'
Callee
// Re-apply every 'log.ctx.*' entry inherited from the caller's pipeline
final prefix = 'log.ctx.'
p6.pipeline.variables().findAll { it.startsWith(prefix) }.each { name ->
p6.log.with name.substring(prefix.length()), p6.pipeline.get(name)
}
p6.log.info 'Batch processing started'
Tip
Centralise the re-apply step in a small helper script that every callee
@includes (see Script Resources) so you avoid
copy/pasting the boilerplate everywhere.
Across p6.script.start (asynchronous, cluster-aware)¶
start submits the target script through the Common Message Bus as a
distributable job. The job may run on another thread or another cluster
node, with a brand-new execution context — neither the caller’s binding
state, nor the caller’s pipeline, nor any thread-local state survive the
hop.
p6.script.start(String id) does not accept custom headers, so you cannot
pass log context as part of the call itself. Trigger the execution through a
CMB message or Camel route that you build yourself, so you control the
headers/attachments — request headers are propagated as attributes to the
started script’s pipeline.
In every case the started script re-applies the entries with p6.log.with
exactly as in the call example above.
Internal platform errors during a DSL call¶
Errors raised by platform internals while a DSL is running (a Camel route,
an HTTP call, a transaction operation, …) are written by their own
loggers, which do not have access to your script’s p6.log context. As a
result, the context you registered with p6.log.with will not appear on
those intermediate internal log lines, even though the failing operation
was triggered by your script.
The final error line is fine, though: if the exception is left
uncaught and bubbles all the way out of the script, the platform’s script
engine emits the failure through your script’s own p6.log instance, so
the full with(...) context is preserved on that line automatically. You
only need a try/catch if you want to emit an extra context-carrying log
line before the failure, decorate it with a custom message, or swallow it
and continue.
Default — let it bubble (context preserved automatically)
p6.log.with 'sidetrade.tenant.id', '303660' with 'batch.id', batchId
// No try/catch needed just to keep the context.
// The script engine will log the uncaught exception through p6.log.
p6.transaction.saveAndRouteTI(invoiceXml, 'direct:p6router.1', pk)
Optional — wrap to add a custom message
p6.log.with 'sidetrade.tenant.id', '303660' with 'batch.id', batchId
try {
p6.transaction.saveAndRouteTI(invoiceXml, 'direct:p6router.1', pk)
} catch (Exception ex) {
// Adds a context-carrying line with your own wording, then rethrows.
throw new P6Exception('Transaction routing failed', ex)
}