Zum Inhalt

Dynamische Includes und Fragmentparameter

Verwende dynamische Includes, wenn ein Descriptor unterschiedliche XML-Fragmente zusammensetzen oder dasselbe Fragment mit verschiedenen Eingaben wiederverwenden soll. DATAMIMIC unterstützt zwei getrennte Mechanismen:

  1. {expression} in include uri wählt die Datei zur Setup-Zeit.
  2. Untergeordnete <property>-Elemente übergeben lokale Werte an ein XML-Fragment. Das Fragment kann seine erwarteten Eingaben mit <param> deklarieren.

Beide Mechanismen gehören zur Core-DSL. Die Platform-spezifische Datei-Injektion pro Lauf wird separat unter Runtime-Properties über die Platform-API injizieren beschrieben.

Eine Include-Datei über Properties auswählen

Properties werden in Dokumentreihenfolge geladen. Ein Platzhalter muss daher vor dem verwendenden <include> definiert sein. Spätere Property-Dateien ersetzen frühere Werte mit demselben Namen.

examples/properties/conf/runtime.properties
1
2
count=2
dynamic_model_path=models/load_performance.xml
examples/properties/models/load_performance.xml
1
2
3
4
5
<setup>
    <generate name="load_records" count="{count}" target="LogExporter">
        <key name="id" generator="IncrementGenerator"/>
    </generate>
</setup>
examples/properties/datamimic.xml
1
2
3
4
<setup>
    <include uri="conf/runtime.properties"/>
    <include uri="{dynamic_model_path}"/>
</setup>

Dieses Muster eignet sich für CI-Varianten, Lasttestmengen und funktionsspezifische Modellfragmente. Jeder aufgelöste Pfad muss innerhalb des Descriptor-Workspace bleiben.

Einen wiederverwendbaren Fragmentvertrag deklarieren

Ein XML-Fragment beschreibt mit <param>, welche Werte Aufrufer liefern dürfen. Ein Parameter kann string, int, enum oder ein sicherer relativer path sein; default macht ihn optional. Enum-Werte werden durch Leerzeichen getrennt.

examples/fragments/fragments/payment.xml
1
2
3
4
5
6
7
8
9
<setup>
    <param name="entity_name" description="Result entity produced by this fragment."/>
    <param name="scheme" type="enum" values="SEPA SWIFT"/>
    <param name="count" type="int" default="2"/>

    <generate name="{entity_name}" count="{count}" target="LogExporter">
        <key name="scheme" script="scheme"/>
    </generate>
</setup>

Der Aufrufer liefert Werte mit untergeordneten <property>-Elementen. constant ist ein literaler Call-Site-Wert; exakt eines von constant und script ist erlaubt.

examples/fragments/datamimic.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<setup>
    <include uri="fragments/payment.xml">
        <property name="entity_name" constant="sepa_payments"/>
        <property name="scheme" constant="SEPA"/>
        <property name="count" constant="3"/>
    </include>

    <include uri="fragments/payment.xml">
        <property name="entity_name" constant="swift_payments"/>
        <property name="scheme" constant="SWIFT"/>
    </include>
</setup>

Der erste Aufruf erzeugt drei SEPA-Datensätze. Der zweite verwendet den deklarierten Standardwert und erzeugt zwei SWIFT-Datensätze. Fehlende Pflichtparameter schlagen mit I618 fehl; ungültige Typen, Enum-Werte oder unsichere Pfade mit I619.

Fragmentparameter pro Quellzeile berechnen

script verwendet normale DATAMIMIC-Ausdruckssemantik ohne Klammern. Innerhalb eines <generate> wird der Ausdruck für jede Aufruferzeile ausgewertet und kann deren Felder und Variablen lesen.

examples/per-row/fragments/payment.xml
1
2
3
4
5
6
7
8
<setup>
    <param name="result_name"/>
    <param name="scheme"/>

    <generate name="{result_name}" count="1" target="LogExporter">
        <key name="scheme" script="scheme"/>
    </generate>
</setup>
examples/per-row/datamimic.xml
1
2
3
4
5
6
7
8
9
<setup>
    <generate name="payments" count="3" target="LogExporter">
        <key name="idx" generator="IncrementGenerator"/>
        <include uri="fragments/payment.xml">
            <property name="result_name" script="idx"/>
            <property name="scheme" script="idx"/>
        </include>
    </generate>
</setup>

Das Fragment wird dreimal mit dem aktuellen idx des direkten Aufrufers ausgeführt. script="{idx}" ist ungültig, weil geschweifte Klammern zur Setup-Attributinterpolation und nicht zur normalen script=-Auswertung gehören.

Scope- und Auswertungsregeln

  • Include-Properties sind beim Parsen und Ausführen des eingebundenen XML-Fragments sichtbar.
  • Verschachtelte Includes erben sie.
  • Sie fließen niemals in den Parent-Descriptor zurück.
  • Ein literales .properties-Include darf keine untergeordneten <property>-Elemente besitzen.
  • Eine dynamische URI, die zu .properties aufgelöst wird, lehnt Child-Properties zur Laufzeit mit I208 ab.
  • Die Bedingung eines .properties-Includes wird zur Parse-Zeit aus zuvor geladenen Properties entschieden.
  • Die Bedingung eines XML-Includes wird zur Laufzeit im aktuellen Ausführungskontext ausgewertet und muss boolesch sein.
  • uri="{expression}" muss einen String liefern und innerhalb des Descriptor-Workspace bleiben.

Fehlerbehandlung

Code Bedeutung
I201 Die Include-Datei wurde nicht gefunden.
I202 Die eingebundenen Properties konnten nicht geparst werden.
I203 / I204 Der Dateityp ist im Setup-/Generate-Kontext nicht unterstützt.
I205 Die Include-Bedingung lieferte keinen booleschen Wert.
I206 Die Auswertung der Include-Bedingung ist fehlgeschlagen.
I207 Der aufgelöste Pfad verlässt den Descriptor-Workspace.
I208 Child-Properties wurden mit einem Properties-Include kombiniert.
I618 Ein erforderlicher Fragmentparameter fehlt.
I619 Ein Fragmentparameter verletzt seinen deklarierten Vertrag.

Auswahl des Mechanismus

  • Verwende Property-Dateien für laufweite Konfiguration und dynamische Fragmentauswahl.
  • Verwende <param> plus <include><property> für ein wiederverwendbares XML-Fragment mit expliziter lokaler Schnittstelle.
  • Verwende constant, wenn der Wert an der Call Site statisch bekannt ist.
  • Verwende script nur, wenn der Wert aus der aktuellen Laufzeitzeile oder dem Scope kommen muss.

Zugehörige Referenzen: <include>, <property> und <param>.