This article explains one way to perform stream elements filtering in TNT4J-Streams—by using dynamic locators to define fields and locators flexibly.
Using Dynamic Locators
TNT4J-Streams allows you to dynamically define field and field-locator parameters. A dynamic reference variable placeholder is defined using ${XXXXX} format, where XXXXX is the name or identifier of another data source configuration entity within the same parser definition.
Sample definition of dynamic field parameters:
<.../>
<parser name="CollectdStatsDataParser" class="com.jkoolcloud.tnt4j.streams.parsers.ActivityMapParser">
<field name="EventType" value="SNAPSHOT"/>
<.../>
<field name="${FieldNameLoc}" locator="values" locator-type="Label" value-type="${ValueTypeLoc}" split="true">
<field-locator id="FieldNameLoc" locator="dsnames" locator-type="Label"/>
<field-locator id="ValueTypeLoc" locator="dstypes" locator-type="Label"/>
</field>
<.../>
</parser>
<.../>The sample shows how to dynamically define field name and value-type parameters by referencing values resolved by FieldNameLoc and ValueTypeLoc locators.
There is also a field attribute split, which states that if the resolved field/locator value is an array or collection, then it should generate as many activity fields as there are items in the array or collection. In this case if the field name is static (or results in the same name from dynamically resolved values), name gets appended with sequential numbering to make field names unique.
Defining combined field parameter values:
<.../>
<parser name="AttributesParser" class="com.jkoolcloud.tnt4j.streams.parsers.ActivityXmlParser">
<field name="${FieldNameLoc}_attr" locator="/entry/*[2]/text()" locator-type="Label" split="true">
<field-locator id="FieldNameLoc" locator="/entry/*[1]/text()" locator-type="Label"/>
</field>
</parser>
<.../>In this sample, the field name value is combined from the dynamic ${FieldNameLoc} and the static _attr parts.
A more complex sample involving field name resolution from a map and using a collection/array element index:
<field name="${ColumnNameLoc}.Column$index" locator="*.2" locator-type="Label" datatype="AsInput">
<field-locator id="ColumnNameLoc" locator="ColumnNames" locator-type="Activity" datatype="AsInput"/>
</field>Locator ColumnNames resolves to a map of e.g. some table column names, where map entry key string ColumnX (X stands for column index) and value is a column name string. Consider locator *.2 resolves a list/array of cell values for that table over RegEx. Dynamic field name definition ${ColumnNameLoc}.Column$index replaces the token $index with the cell index (from the list/array), uses the map resolved by the ColumnNameLoc locator, and finally picks the map entry value with the key ColumnX (Column0, Column1 and so on...).
Sample showing use of another field resolved value:
<.../>
<parser name="TransferSetParser" class="com.jkoolcloud.tnt4j.streams.parsers.ActivityXmlParser">
<.../>
<field name="Direction" locator="name(//*[1])" locator-type="Label" transparent="true"/>
<field name="ResourceName" formattingPattern="{0}={1};Agent={2}">
<!--resolves FILE or QUEUE-->
<field-locator locator="name(//*/*)" locator-type="Label">
<field-map-ref resource="MFT_MAPPINGS.Resource"/>
</field-locator>
<!--resolves file or queue name -->
<field-locator locator="ts:getFileName(/${Direction}/file)" locator-type="Label" required="false"/>
<field-locator locator="ts:getObjectName(/${Direction}/queue)" locator-type="Label" required="false"/>
<!-- agent-->
<field-locator locator="/transaction/${Direction}Agent/@agent" locator-type="Label" required="false"/>
</field>
</parser>
<.../>The sample configuration defines the parser field Direction resolving a value such as source or destination. Then, the ResourceName field’s locators use this value when constructing an actual XPath expression e.g., /transaction/${Direction}Agent/@agent, to resolve the value from the XML data.
When using the field/field-locator attribute locator-type="Activity", define the field name as the locator value without ${}, e.g.:
<.../> <parser name="TransferSetParser" class="com.jkoolcloud.tnt4j.streams.parsers.ActivityXmlParser"> <.../> <field name="Checksum" locator="//*/checksum" locator-type="Label" required="false"/> <field name="Correlator" locator="Checksum" locator-type="Activity" required="false"/> <.../> </parser> <.../>
For the next option, see the article on caching streamed data field values.