Click here to learn the basics of TNT4J Events Field Mappings.
Stacked Parsers
In stream parsers configurations you are allowed to use the stacked parsers technique: This is when some field data parsed by one parser can be forwarded to another parser for more detailed parsing: the envelope-message approach.
To define stacked parser(s), you have to define parser-ref tag(s) under parser field or embedded-activity definition.
embedded-activity is a tag field alias, used to define a set of locator-resolved data transparent to the parent activity but useful for creating a separate set of related child activities.
If the upper-level parser resolved data is incompatible with the stacked parser, the stacked parser is not applied to parse that data.
Sample:
<tnt-data-source
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="tnt-data-source.xsd">
<parser name="AccessLogParserCommon" class="com.jkoolcloud.tnt4j.streams.custom.parsers.ApacheAccessLogParser">
<.../>
</parser>
<parser name="AccessLogParserExt" class="com.jkoolcloud.tnt4j.streams.custom.parsers.ApacheAccessLogParser">
<.../>
</parser>
<parser name="SampleJMSParser" class="com.jkoolcloud.tnt4j.streams.parsers.ActivityJMSMessageParser">
<.../>
<field name="MsgBody" locator="ActivityData" locator-type="Label">
<parser-ref name="AccessLogParserCommon"/>
</field>
<.../>
<embedded-activity name="InternalActivity" locator="OtherActivityData" locator-type="Label">
<parser-ref name="AccessLogParserExt" aggregation="Merge"/>
<parser-ref name="AccessLogParserCommon" aggregation="Relate"/>
</embedded-activity>
<.../>
</parser>
<stream name="SampleJMStream" class="com.jkoolcloud.tnt4j.streams.inputs.JMSStream">
<.../>
<parser-ref name="SampleJMSParser"/>
</stream>
</tnt-data-source>See 'JMS text message' sample for full configuration definition.
In this sample stream named SampleJMStream has primary parser reference SampleJMSParser. It parses data received as JMS message ( envelope). Field MsgBody carries JMS message payload data (message). In this sample, consider that we are sending an Apache Access log entry as JMS message payload. So to parse that Apache access log entry we use stacked parser named AccessLogParserCommon.
After processing one JMS message TNT4J activity event will contain fields mapped by both SampleJMSParser and AccessLogParserCommon at the end.
See Parser matching data or parsing context for parser reference configuration details.
Relative Locators
-
^.fieldName- stacked parserActivitytype locator prefix^.can be used to access parent parser (one stacked parser was invoked from) produced activity entity field value, where field name is defined by locator tokenfieldName. E.g.:<tnt-data-source xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="tnt-data-source.xsd"> <parser name="AccessLogParserCommon" class="com.jkoolcloud.tnt4j.streams.custom.parsers.ApacheAccessLogParser"> <.../> <field name="ValueFromParent" locator="^.StaticValue" locator-type="Activity"/> </parser> <parser name="SampleJMSParser" class="com.jkoolcloud.tnt4j.streams.parsers.ActivityJMSMessageParser"> <.../> <field name="StaticValue" value="SampleJMSParser_Value" transparent="true"/> <.../> <embedded-activity name="InternalActivity" locator="OtherActivityData" locator-type="Label"> <parser-ref name="AccessLogParserCommon" aggregation="Relate"/> </embedded-activity> <.../> </parser> <.../> </tnt-data-source>AccessLogParserCommonuses fieldValueFromParentlocator^.StaticValueto fill in value defined inSampleJMSParserparser fieldStaticValue. After parsing, fieldValueFromParentwill have valueSampleJMSParser_Value. -
^.child[groupName.chIndex].fieldName(short form^.child[chIndex].fieldNameor^.child[groupName].fieldName) - stacked parser aggregating activity entities usingRelatemethod,Activitytype locators can resolve field values from these child entities using this relative locator. Child activity entities are grouped by stacked parser names within parent entity, thus it is possible to access child entity field values from different stacked parsers under same parent activity. Locator pattern tokens mean the following:-
^.- is locator prefix to access parent activity entity -
child- is predefined value to resolve child entity -
groupName- is activity children group name, or if this token is missing - then group name is current stacked parser name -
childIndex- is the child index in the defined group, or if this token is missing - then child index is ordinal index of current stacked parser produced activity entity -
fieldName- is child activity entity field name
-
-
child[groupName.matchExpression].fieldName(can be prefixed^.to access parent activity entity children) - resolves child activity entity matching expressionmatchExpressionfieldfieldNamevalue. Match expression can be field value comparison with variable or static value, like this:fieldName=${variable}e.g.guid=${txHash}Locator definition samples:
<field name="mainReason" locator="^.child[0].reason" locator-type="Activity"/> <field name="mainReason" locator="^.child[OtherParser].reason" locator-type="Activity"/> <field name="mainReason" locator="^.child[InputsParser.0].reason" locator-type="Activity"/> <field name="mainReason" locator="${child[TransactionParser.guid=${txHash}].tokenName}" locator-type="Activity"/>Parsers sample:
<parser name="tokenAttributesBySLP" class="com.jkoolcloud.tnt4j.streams.parsers.ActivityMapParser" manualFieldsOrder="true"> <.../> <field name="transactionType" locator="transactionType" locator-type="Label" datatype="AsInput"/> <.../> </parser> <parser name="voutParser" class="com.jkoolcloud.tnt4j.streams.parsers.ActivityMapParser" manualFieldsOrder="true"> <field name="EventType" value="Snapshot"/> <.../> <field name="slpTxAttributes" locator="slpAttributes" locator-type="Label" transparent="true"> <parser-ref name="tokenAttributesBySLP" aggregation="Merge"/> </field> <field name="transactionIndex" locator="n" datatype="Number" locator-type="Label"/> <field name="transactionType" locator="^.child[0].transactionType" locator-type="Activity"/> <.../> </parser> <parser name="vinParser" class="com.jkoolcloud.tnt4j.streams.parsers.ActivityMapParser"> <field name="EventType" value="Snapshot"/> <.../> <field name="tinIndex" locator="^.child[voutParser.0].transactionIndex" locator-type="Activity"/> <.../> </parser> <parser name="TransactionParserEnhanced" class="com.jkoolcloud.tnt4j.streams.parsers.ActivityJsonParser" manualFieldsOrder="true"> <field name="EventType" value="Event"/> <.../> <embedded-activity name="vin" locator="$.result.vin" locator-type="Label"> <parser-ref name="vinParser" aggregation="Relate"/> </embedded-activity> <embedded-activity name="vout" locator="$.result.vout" locator-type="Label"> <parser-ref name="voutParser" aggregation="Relate"/> </embedded-activity> <.../> </parser>Parent activity entity (event) is created by parser named
TransactionParserEnhanced. This parser has two fieldsvinandvoutresolving array of JSON maps and referring stacked parsersvinParserandvoutParserand aggregating child activity entities (snapshots) usingRelatemethod.voutParseritself has fieldslpTxAttributesreferring stacked parsertokenAttributesBySLPappending fieldtransactionTypetovoutParserparser created snapshot. ConsiderTransactionParserEnhancedpasses different contents of maps intovoutParserand first map (child) entryslpAttributeshas value map entrytransactionType, the rest - not. But we want all produced snapshots to have fieldtransactionTypeand to have value defined in first child. Locator^.child[0].transactionTypeallows us to access that wanted value from first child (in case current child entry is the first one, field value is simply remapped to itself). Meanwhile, parservinParsercan accessvoutParserproduced snapshots fieldtransactionIndexvalue since they both "are under" same parent parserTransactionParserEnhanced.When two or more stacked parsers produce related sets of activity entities (having the same count of child entities), it may be useful to access the corresponding (auto-mapped by index) activity entity. In such a case, using child locator pattern
^.child[groupName].fieldNameallows to perform such index auto mapping from current stacked parser children set togroupNamedefined group children set. -
^.XPathExpression-ActivityXMLParserstacked parser fieldLabeltype locator prefix^.can be used to access parent parser (one stacked parser was invoked from) parsed document/node value using XPath expression, defined by tokenXPathExpression. E.g.:<!-- parser handles XML having root tags <source> or <destination> --> <parser name="TransferSetParser" class="com.jkoolcloud.tnt4j.streams.parsers.ActivityXmlParser"> <field name="LastModified" locator="/source/file/@last-modified" locator-type="Label" required="false"/> <.../> <!-- access some field values from parent context document --> <field name="SourceSystemName" locator="^./transaction/sourceAgent/@agent" locator-type="Label"/> <field name="DestinationSystemName" locator="^./transaction/destinationAgent/@agent" locator-type="Label"/> <field name="Correlator" locator="^./transaction/@ID" locator-type="Label" datatype="String" format="string"/> <.../> </parser> <!-- parser handles XML having root tag <item> --> <parser name="TransferSetItemParser" class="com.jkoolcloud.tnt4j.streams.parsers.MessageActivityXmlParser"> <field name="ResultCode" locator="/item/status/@resultCode" locator-type="Label" datatype="Number" transparent="true"/> <.../> <!-- field passes '/item/source' or '/item/destination' node to be root for stacked parser --> <embedded-activity name="TS_ITEM" locator="/item/*[name(.) = 'source' or name(.) = 'destination']" locator-type="Label"> <parser-ref name="TransferSetParser" aggregation="Relate"/> </embedded-activity> <.../> </parser> <!-- parser handles XML having root tag <transaction> --> <parser name="ProgressEventParser" class="com.jkoolcloud.tnt4j.streams.parsers.MessageActivityXmlParser"> <field name="EventType" value="Event"/> <field name="UserName" locator="/transaction/originator/userID" locator-type="Label"/> <field name="Location" locator="/transaction/originator/hostName" locator-type="Label"/> <.../> <!-- field passes '/transaction/transferSet/item' node to be root for stacked parser --> <embedded-activity name="TRANSFERSET" locator="/transaction/transferSet/item" locator-type="Label"> <parser-ref name="TransferSetItemParser" aggregation="Merge"/> </embedded-activity> <.../> </parser>
Resolved Activity Entities Aggregation
Stacked parsers sample configuration tag <parser-ref> has attribute aggregation. This attribute defines method of resolved activity data aggregation into parent activity. Attribute has two possible values:
Merge- resolved activity entity fields are merged into parent activity. NOTE: Parent activity entity will contain all fields processed by all stacked parsers. This is default value when attributeaggregationdefinition is missing in configuration.-
Relate- resolved activity entities are collected as children of parent activity. As a result there will be one parent activity entity having collection of child activities resolved by stacked parsers. NOTE: this value has aliasJoinleft for backward compatibility, but it is not recommended using it anymore and should be changed right away for existing configurations. Activity entities can have these relations:-
ACTIVITY- can have any entity as child:ACTIVITY,EVENT,SNAPSHOTorDATASET -
EVENT- can have onlySNAPSHOTorDATASETas a child -
SNAPSHOT/DATASET- can't have any child entities
Be sure that each parser or sub-parser that creates an activity entity to be sent to jKool/AP Insight as a JSON record has a field line:
<field name="EventType" value="vvvv"/>
where
vvvvis one of values:ACTIVITY,SNAPSHOT/DATASETorEVENT(EVENTalso maps from valuesOTHER,CALL,START,STOP,OPEN,CLOSE,SEND,RECEIVE,INQUIRE,SET,BROWSE,ADD,UPDATE,REMOVE,CLEAR,DATAGRAM). NOTE: If none of the above values applies to your case, you may useNOOPvalue. Then, however, the activity entity JSON record will not be created and not sent to jKoolCloud, e.g.:<field name="EventType" value="NOOP"/>
-
Relate_Flat- resolved activity entities are collected as children of root activity entity. It is useful when related activity entities hierarchy can become as tree structure, but because ofEVENTandSNAPSHOT/DATASEThierarchy restrictions (seeRelatedefinition), it can't be sent to JKool directly.
For a Relate and Relate_Flat type aggregations there is related stream output parameter SplitRelatives:
<stream name="SampleJMStream" class="com.jkoolcloud.tnt4j.streams.inputs.JMSStream">
<property name="SplitRelatives" value="true"/>
<.../>
<parser-ref name="SampleJMSParser"/>
</stream>or
<?xml version="1.0" encoding="utf-8"?>
<tnt-data-source
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://meshiq-xsd.s3.amazonaws.com/streams/tnt-data-source.xsd">
<java-object name="StreamOutput" class="com.jkoolcloud.tnt4j.streams.outputs.JKCloudActivityOutput">
<property name="SplitRelatives" value="true"/>
</java-object>
<.../>
<stream name="SampleJMStream" class="com.jkoolcloud.tnt4j.streams.inputs.JMSStream">
<.../>
<parser-ref name="SampleJMSParser"/>
<reference name="StreamOutput"/>
</stream>
</tnt-data-source>It allows sending as many activity entities to jKool as there are child activity entities resolved by stacked parsers, merging those child activity entities' data with the parent activity entity data. E.g., when parser builds activity entities relations like this (4 entities in total):
ParentActivity
+ ChildEvent1
+ ChildEvent2
+ ChildEvent3stream output will send such entities to jKool (3 entities in total):
Event1 having ChildEvent1 + ParentActivity data Event2 having ChildEvent2 + ParentActivity data Event3 having ChildEvent3 + ParentActivity data
This is useful when streamed data is aggregated in one data package, like JSON/XML data having some header values and array of payload entries (see mft-tracking sample XML's), but you need only those payload entries maintaining some header data contained values to be set to jKool. Or like in mft_fte sample, when MFT transaction progress event transferSet node having source and destination definitions, and you need to split them into separate events maintaining some transaction data values.
Field Value Transformations
In stream configurations, you can define field- or locator-resolved value transformations. In general, transformations perform resolved activity value post-processing before sending it to meshIQ: e.g., extracts file name from resolved activity file path.
To pass a resolved field/locator value to a transformation script/expression, use the predefined variable placeholder $fieldValue. You can also use parser-defined field names as script/expression variables having the format ${FIELD_NAME} to access resolved activity entity fields like ${EventType} or ${Trace.HighResTime}. The referenced fields must be within the same parser definition.
To access the transformation-performing field/locator name/id, use the predefined variable placeholder $fieldName.
Transformation Definition
To define transformations stream configuration token <field-transform> shall be used. Attributes:
-
name- name of transformation (optional). -
lang- transformation script/expression language. Can be one ofgroovy,javascriptorxpath. Default value -javascript. -
beanRef- transformation implementing bean reference. -
phase- defines activity data resolution phase, when transformation has to be applied. Can be one ofraw,formattedoraggregated.rawandformattedvalues are applicable for field locator resolved value transformation, whileaggregatedis default for transformation having references to activity entity fields.
Token body is used to define transformation script/expression code.
Valid transformation configuration should define beanRef, or have script/expression code defined in token body data (<![CDATA[]]>).
TNT4J-Streams predefined custom XPath functions
To use TNT4J-Streams predefined functions namespace ts: shall be used.
Streams predefined custom XPath functions to be used in transformation expressions:
-
ts:getFileName(filePath)- implemented by transformation beancom.jkoolcloud.tnt4j.streams.transform.FuncGetFileName. Retrieves file name from provided file path. -
ts:getObjectName(objectFQN, options)- implemented by transformation beancom.jkoolcloud.tnt4j.streams.transform.FuncGetObjectName. Retrieves desired object name from provided fully qualified object name. Function supported options:- resolution options:
DEFAULT,BEFORE,AFTER,REPLACE,FULL. (Optional) - search symbols. (Optional)
- replacement symbols. (Optional)
- resolution options:
-
ts:replaceRegex(text, regex, replacement)- implemented by transformation beancom.jkoolcloud.tnt4j.streams.transform.FuncReplaceRegex. Replacesregexmatching segments within providedtextwith providedreplacement. -
ts:findRegex(text, regex, group)- implemented by transformation beancom.jkoolcloud.tnt4j.streams.transform.FuncFindRegex. Findsregexmatching segment within providedtext.
You may also define your own customized XPath functions. To do this your API has to:
- implement interface
javax.xml.xpath.XPathFunction - register function by invoking
com.jkoolcloud.tnt4j.streams.utils.StreamsXMLUtils.registerCustomFunction(functionName, function).
E.g.:
public class YourTransform implements XPathFunction {
@Override
public Object evaluate (List args) {
// retrieve expression code provided arguments and make transformation here.
}
}
...
StreamsXMLUtils.registerCustomFunction("yourTransformation",new YourTransform());
...then you can use it from stream configuration:
<field name="InvoiceFileFromFunction" locator="7">
<field-transform name="fileNameF" lang="xpath">
ts:yourTransformation($fieldValue, "arg2", "arg3")
</field-transform>
</field>Those functions can be also used in XPath expressions of ActivityXMLParser ( or MessageActivityXMLParser) field locators. For example:
<parser name="XMLParser" class="com.jkoolcloud.tnt4j.streams.parsers.ActivityXmlParser">
<.../>
<field name="MFT_SRC_FILE_NAME" locator="ts:getFileName(/transaction/transferSet/item/source/file)" locator-type="Label"/>
<.../>
</parser>Use samples of ts:getObjectName() (consider XPath /transaction/transferSet/item/source/queue points to queue named SomeQueueName@Agent1):
<parser name="XMLParser" class="com.jkoolcloud.tnt4j.streams.parsers.ActivityXmlParser">
<.../>
<!-- to get queue name without agent: 'SomeQueueName' -->
<field name="MFT_SRC_QUEUE_NAME" locator="ts:getObjectName(/transaction/transferSet/item/source/queue)" locator-type="Label"/>
<!-- to get queue name without agent (part before FQN delimiter): 'SomeQueueName'-->
<field name="MFT_SRC_QUEUE_NAME" locator="ts:getObjectName(/transaction/transferSet/item/source/queue, 'BEFORE', '@')" locator-type="Label"/>
<!-- to get agent name (part after FQN delimiter): 'Agent1'-->
<field name="MFT_SRC_AGENT_NAME" locator="ts:getObjectName(/transaction/transferSet/item/source/queue, 'AFTER', '@')" locator-type="Label"/>
<!-- to get queue fully qualified name with '@' replaced to '_': 'SomeQueueName_Agent1' -->
<field name="MFT_SRC_QUEUE_FQN_REPLACED" locator="ts:getObjectName(/transaction/transferSet/item/source/queue, 'REPLACE', '@', '_')" locator-type="Label"/>
<!-- to get queue fully qualified: 'SomeQueueName@Agent1'-->
<field name="MFT_SRC_QUEUE_FQN" locator="ts:getObjectName(/transaction/transferSet/item/source/queue, 'FULL')" locator-type="Label"/>
<.../>
</parser>Stream Elements Transformations
- Field value transformation
<field name="Field" separator=",">
<field-transform name="toUpper" lang="groovy">
$fieldValue.toUpperCase()
</field-transform>
<field-locator locator="loc1" locator-type="Label"/>
<field-locator locator="loc2" locator-type="Label"/>
<.../>
</field>When transformation is defined for a field containing multiple locators, field value transformation is applied to all field locators aggregated field value.
Sample above states that field value combined from locators loc1 and loc2 and separated by , should be upper-cased. For example locator loc1 resolves value value1, locator loc2 resolves value vaLue2. Then field value before transformations is value1,vaLue2 and field value after transformation is VALUE1,VALUE2.
- Field locator value transformation
<field name="Field" separator=",">
<field-locator locator="loc1" locator-type="Label">
<field-transform name="toUpper" lang="groovy" phase="raw">
$fieldValue.toUpperCase()
</field-transform>
</field-locator>
<field-locator locator="loc2" locator-type="Label">
<field-transform name="toUpperConcat" lang="groovy" phase="formatted">
$fieldValue.toUpperCase() + "_transformed"
</field-transform>
</field-locator>
<.../>
</field>Sample above states that locator loc1 resolved value should be upper-cased and locator loc2 resolved value should be upper-cased and concatenated with string _transformed. Then those transformed values should be aggregated to field value separated by , symbol. For example locator loc1 resolved value value1, then after transformation value is changed to VALUE1. Locator loc2 resolved value value2, then after transformation value is changed to VALIUE2_transformed. Field aggregates those locators values to VALUE1,VALUE2_transformed.
- Field/locator value transformation using additional activity entity fields
<field name="EventName" locator="enLoc" locator-type="Label"/>
<field name="EventType" locator="etLoc" locator-type="Label"/>
<.../>
<field name="Field" value="activity">
<field-transform name="toUpperConcat" lang="groovy">
$fieldValue.toUpperCase() + "=" + ${EventType} + " : " + ${EventName}
</field-transform>
<.../>
</field>Sample above defines fields EventName and EventType resolving values from streamed activity data. Then field named Field uses transformation to build value from predefined initial value activity and fields EventName, EventType resolved values. For example field EventName resolved value Transcation_X and EventType resolved value is SEND. Then after transformation field Field value becomes as ACTIVITY=SEND:Transcation_X.
- locator defined transformations are applied before field value transformations.
- it is possible to define multiple transformations for same stream element (field/locator). In that case transformations are applied sequentially where input of applied transformation is output of previous transformation.
- it is allowed to combine field and locators transformations within same stream field scope setting transformations for both field and locators independently.
- when "short form" of field-locator configuration is used, transformation is bound to locator (because field-locator relation is 1:1 and resolved value is same for locator and for field). Example:
<field name="Correlator" locator="3">
<field-transform name="concat">
"corel_" + $fieldValue
</field-transform>
</field>Transformation Definition Samples
- Groovy script/expression
<field name="ApplName" value="orders">
<field-transform name="toUpper" lang="groovy">
$fieldValue.toUpperCase().center(30)
</field-transform>
</field>This sample uppercases the resolved value and makes a "centered" (padded and tailed with space symbols) 30- character string.
- JavaScript script/expression
<field name="UserName" locator="4">
<field-transform name="toUpper" lang="javascript">
$fieldValue.toUpperCase()
</field-transform>
</field>This sample uppercases the resolved value.
Or (using default attribute lang value)
<field name="Correlator" locator="3">
<field-transform name="concat">
"corel_" + $fieldValue
</field-transform>
</field>This sample concatenates the string corel_ and the resolved value.
JavaScript/Groovy-based transformations default import packages:
com.jkoolcloud.tnt4j.corecom.jkoolcloud.tnt4j.utilscom.jkoolcloud.tnt4j.uuidcom.jkoolcloud.tnt4j.streams.utilscom.jkoolcloud.tnt4j.streams.fieldsorg.apache.commons.lang3org.apache.commons.collections4
so you are allowed to directly use classes from those packages in script code, e.g.:
<field-transform lang="groovy" name="FieldSubstring10">
<![CDATA[
StringUtils.substring($fieldValue, 0, 10)
]]>
</field-transform>- XPath expression
<field name="InvoiceFileFromFunction" locator="7">
<field-transform name="fileNameF" lang="xpath">
concat(ts:getFileName($fieldValue), "_cust")
</field-transform>
</field>This sample retrieves file name from resolved file path (contained in $fieldValue) and concatenates it with string _cust.
- Transformation bean
To make custom Java Bean based transformations your API should implement interface com.jkoolcloud.tnt4j.streams.transform.ValueTransformation<V, T>.
<tnt-data-source
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="tnt-data-source.xsd">
<.../>
<java-object name="getFileNameTransform" class="com.jkoolcloud.tnt4j.streams.transform.FuncGetFileName"/>
<.../>
<field name="InvoiceFileFromBean">
<field-locator locator="7">
<field-transform beanRef="getFileNameTransform"/>
</field-locator>
</field>
<.../>This sample shows how to invoke Java Bean defined transformation. Class com.jkoolcloud.tnt4j.streams.transform.FuncGetFileName implements custom XPath function to get file name from provided file path. Field/locator value mapping to function arguments is performed automatically and there is no need to define additional mapping.
- Building field value from other activity entity fields values using transformations
Sometimes field value may be some combination of other activity entity fields values. To achieve such goal, transformations come in hand.
<field name="MQTrace_HighresTime" locator="MQGACF_ACTIVITY_TRACE.MQIAMO64_HIGHRES_TIME" locator-type="Label" datatype="Timestamp"
units="Microseconds"/>
<field name="ElapsedTime" locator="MQGACF_ACTIVITY_TRACE.MQIAMO64_QMGR_OP_DURATION" locator-type="Label"
datatype="Number" units="Microseconds"/>
<field name="StartTime" value="">
<field-transform lang="groovy" name="StartTimeTransform">
${MQTrace_HighresTime} / 1000
</field-transform>
</field>
<field name="EndTime" value="">
<field-transform lang="groovy" name="EndTimeTransform">
${MQTrace_HighresTime} + ${ElapsedTime}
</field-transform>
</field>The sample shows how to make activity entity fields StartTime and EndTime values using IBM MQ trace- resolved high-resolution values (in microseconds) of operation start and elapsed times.
StartTime is evaluated using a Groovy transformation deviding the field MQTrace_HighresTime value by 1000 to get the time in milliseconds.
EndTime is evaluated using a Groovy transformation, adding the MQTrace_HighresTime and ElapsedTime field values to produce the final value in microseconds.
The initial value for those fields is set to value="".
But it is allowed to set there any default initial value or use value locator(s),
if it may be useful for a transformation expression evaluation. In that case
to access initial value use expression variable $fieldValue.