Macro Substitution
Previously, the configurations of plugins in an ETL pipeline could not be changed after the pipeline's deployment. Macro substitution provides pipeline developers and operators the ability to configure plugin settings on a run-to-run basis for settings that may be unknown at the time of configuration.
Specifying Substitutions
Macro substitution provides two types of substitutions through property lookups and macro functions. Property lookups are specified through key-value pairs. There are two ways to specify these key-value pairs.
- Set a key-value pair in the runtime arguments or preferences for the physical pipeline.
- A Custom Action or Hydrator Action can be run in the first stage of a pipeline and set a key-value argument through a workflow token.
In order to enable a plugin property as macro-substitutable, the property must be both annotated as macro-enabled and provided proper macro syntax at configuration time.
...
==============
CDAP CHANGES
==============
Macro Substitution
Pluigins now support macro-substitutable properties that allow placeholders for properties that are unknown at configure time but known at runtime.
Macro Annotation
In order to enable macro substitution for a property, use the @Macro annotation on the property field in a plugin's configuration class. As such, macros are disabled for all fields by default. For example:
Code Block | ||
---|---|---|
| ||
public class TableSinkConfig extends PluginConfig {
@Name(Properties.Table.NAME)
@Description("Name of the table. If the table does not already exist, one will be created.")
// The name of the table can be specified by a runtime macro
@Macro
private String name;
@Name(Properties.Table.PROPERTY_SCHEMA)
@Description("schema of the table as a JSON Object. If the table does not already exist, one will be " +
"created with this schema, which will allow the table to be explored through Hive. If no schema is given, the " +
"table created will not be explorable.")
@Nullable
private String schemaStr;
@Name(Properties.Table.PROPERTY_SCHEMA_ROW_FIELD)
@Description("The name of the record field that should be used as the row key when writing to the table.")
private String rowField;
} |
Macro Evaluators
Macro Evaluators are an addition to the CDAP platform that perform the substitution of parsed macro arguments. These evaluators by default support two operations.
Property Lookups
Code Block | ||
---|---|---|
| ||
${macro-name} |
The syntax ${macro-name} will be replaced with whatever value was specified for the key "macro-name."
Macro Functions
Macro functions allow more complex logic to be run before a substitution occurs and use the following syntax:
Code Block | ||
---|---|---|
| ||
${macroFunction(arg1,arg2,arg3)} |
The function "macroFunction" function will perform some computation with the provided arguments: arg1, arg2, and arg3. The syntax will be replaced with whatever macroFunction evaluates to given the provided arguments.
Expansion Capabilities
Macro parsing is handled by the CDAP platform and supports the following capabilities:
Multiple Macros
A single property can have multiple macros either consecutive or spread out.
Code Block | ||
---|---|---|
| ||
${host}/${path}:${port} --> example.com/index.html:80 |
Nested Macros
A macro can have another macro nested inside. Nested macros are expanded before the outer macro. If there are multiple nested macros within a single enclosing macro, they are evaluated from right-to-left. Based on the specified substitutions, the following substitutions could be possible based on the value of "host-suffix":
Code Block | ||
---|---|---|
| ||
Option 1. ${hostname${host-suffix}} --> ${hostname-use-suffix} --> example.com/index.html:80
Option 2. ${hostname${host-suffix}} --> ${hostname-dont-use-suffix} --> example.com |
Recursive Macros
A macro can be substituted with another macro if specified as such. For example, the following key-value pair:
Code Block | ||
---|---|---|
| ||
full-server-address: ${hostname}/${path}:${port} |
would lead to the following expansion:
Code Block | ||
---|---|---|
| ||
${full-server-address} --> ${hostname}/${path}:${port} --> example.com/index.html:80 |
In the case that a single macro expands to multiple macros, the new macros will be substituted from right-to-left. Recursive expansion is currently supported up to a maximum depth of 10.
Macro Syntax Escaping
Macro syntax can be escaped. To escape existing syntax, use the backslash '\' character. Backslashes themselves must also be escaped, so to use a backslash, use two consecutive backslashes '\\'. For example, the following syntax:
Code Block | ||
---|---|---|
| ||
${\${escaped-macro-literal\}} |
would be look up the specified property with a key of: ${escaped-macro-literal}.
===================
HYDRATOR CHANGES
===================
Macro Substitution
Previously, the configurations of plugins in an ETL pipeline could not be changed after the pipeline's deployment. Macro substitution provides pipeline developers and operators the ability to configure plugin settings on a run-to-run basis for settings that may be unknown at the time of configuration.
Specifying Substitutions
Macro substitution provides two types of substitutions through property lookups and macro functions. Property lookups are specified through key-value pairs. There are two ways to specify these key-value pairs.
- Set a key-value pair in the runtime arguments or preferences for the physical pipeline.
- Custom Hydrator Actions can be run in the first stage of a pipeline and set a key-value argument through a workflow token.
In order to enable a plugin property as macro-substitutable, the property must be both annotated as macro-enabled and provided proper macro syntax at configuration time.
Information on setting preferences and runtime arguments is in the CDAP Administration Manual, Preferences. These can be set with the HTTP Lifecycle and Preferences RESTful APIs.
Syntax
In addition to a plugin property being annotated with with @Macro, proper macro syntax must be provided to the property field at configure time. There are two valid macro syntaxes, property lookups and and macro functions.
Property
...
Lookups
Macro property lookups are simple key-value substitutions that use the following syntax:
...
At runtime, the syntax ${macro-name} will be replaced with whatever value was specified for the key "macro-name." For instance, you might not know the name of a source stream until runtime. You could use, in the source stream's Stream Name configuration:
Code Block |
---|
Macro Function
Macro functions allow more complex logic to be run before a substitution occurs and use the following syntax:
Code Block | ||
---|---|---|
| ||
${macroFunction(arg1, arg2, arg3)} |
...
| ||
${source-stream-name} |
and in the runtime arguments (or preferences) set a key-value pair such as:
Code Block | ||
---|---|---|
| ||
source-stream-name: myDemoStream |
Macros can be referential. You might have a server that refers to a hostname and port, and specify this substitution:
Code Block | ||
---|---|---|
| ||
server-address: ${hostname}:${port} |
and these runtime arguments:
Code Block | ||
---|---|---|
| ||
hostname: my-demo-host.example.com
port: 9991 |
In a pipeline configuration, you could configure a property with:
Code Block | ||
---|---|---|
| ||
${server-address} |
expecting that it would be replaced with:
Code Block | ||
---|---|---|
| ||
my-demo-host.example.com:9991 |
Lookup Precedence
For property lookup macros, substitutions set through workflow tokens take precedence over those set through runtime arguments and preferences.
Macro Functions
Currently, there are two support macro functions, logicalStartTime and secure. Note that whitespace is significant in arguments.
logicalStartTime
Code Block | ||
---|---|---|
| ||
${logicalStartTime(timeFormat,offset)} |
The logicalStartTime macro function takes in a time format and an optional offset as arguments and uses the logical start time of a pipeline to perform the substitution. For example, suppose the logical start time of a pipeline run is 2016-01-01T00:00:00 and the following macro is provided:
Code Block | ||
---|---|---|
| ||
${logicalStartTime(yyyy-MM-dd'T'HH-mm-ss,1d-4h+30m)} |
The format is yyyy-MM-dd'T'HH-mm-ss and the offset is 1d-4h+30m before the logical start time. This means the macro will be replaced with 2015-12-31T03:30:00, since the offset translates to 20.5 hours. Therefore, the entire macro evaluates to 20.5 hours before midnight of new years 2016.
secure
Code Block | ||
---|---|---|
| ||
${secure(key)} |
The secure macro function takes in a single key as an argument and looks up the key's associated string value from the Secure Store. In order to perform the substitution, the key provided as an argument must already exist in the secure store. This is useful for performing a substitution with sensitive data.
For example, for a plugin that connects to a MySQL database, you can configure the "password" property field with:
Code Block | ||
---|---|---|
| ||
${secure(mysql-password)} |
which will pull "mysql-password" from the secure store at runtime.