Skip to content

Latest commit

 

History

History
306 lines (226 loc) · 11.3 KB

component-configuration.adoc

File metadata and controls

306 lines (226 loc) · 11.3 KB

Defining component layout and configuration

The component configuration is defined in the <component_name>Configuration.java file of the package. It consists in defining the configurable part of the component that will be displayed in the UI.

To do that, you can specify parameters. When you import the project in your IDE, the parameters that you have specified in the starter are already present.

Important
All input and output components must reference a dataset in their configuration. Refer to Defining datasets and datastores.

Parameter name

Components are configured using their constructor parameters. All parameters can be marked with the @Option property, which lets you give a name to them.

For the name to be correct, you must follow these guidelines:

  • Use a valid Java name.

  • Do not include any . character in it.

  • Do not start the name with a $.

  • Defining a name is optional. If you don’t set a specific name, it defaults to the bytecode name. This can require you to compile with a -parameter flag to avoid ending up with names such as arg0, arg1, and so on.

Examples of option name:

Option name Valid

myName

[check]

my_name

[check]

my.name

[times]

$myName

[times]

Parameter types

Parameter types can be primitives or complex objects with fields decorated with @Option exactly like method parameters.

Important
It is recommended to use simple models which can be serialized in order to ease serialized component implementations.

For example:

class FileFormat implements Serializable {
    @Option("type")
    private FileType type = FileType.CSV;

    @Option("max-records")
    private int maxRecords = 1024;
}

@PartitionMapper(name = "file-reader")
public MyFileReader(@Option("file-path") final File file,
                    @Option("file-format") final FileFormat format) {
    // ...
}

Using this kind of API makes the configuration extensible and component-oriented, which allows you to define all you need.

The instantiation of the parameters is done from the properties passed to the component.

Primitives

A primitive is a class which can be directly converted from a String to the expected type.

It includes all Java primitives, like the String type itself, but also all types with a org.apache.xbean.propertyeditor.Converter:

  • BigDecimal

  • BigInteger

  • File

  • InetAddress

  • ObjectName

  • URI

  • URL

  • Pattern

  • LocalDateTime

  • ZonedDateTime

Mapping complex objects

The conversion from property to object uses the Dot notation.

For example, assuming the method parameter was configured with @Option("file"):

file.path = /home/user/input.csv
file.format = CSV

matches

public class FileOptions {
    @Option("path")
    private File path;

    @Option("format")
    private Format format;
}

List case

Lists rely on an indexed syntax to define their elements.

For example, assuming that the list parameter is named files and that the elements are of the  FileOptions type, you can define a list of two elements as follows:

files[0].path = /home/user/input1.csv
files[0].format = CSV
files[1].path = /home/user/input2.xml
files[1].format = EXCEL
Tip
if you desire to override a config to truncate an array, use the index length, for example to truncate previous example to only CSV, you can set:
files[length] = 1

Map case

Similarly to the list case, the map uses .key[index] and .value[index] to represent its keys and values:

// Map<String, FileOptions>
files.key[0] = first-file
files.value[0].path = /home/user/input1.csv
files.value[0].type = CSV
files.key[1] = second-file
files.value[1].path = /home/user/input2.xml
files.value[1].type = EXCEL
// Map<FileOptions, String>
files.key[0].path = /home/user/input1.csv
files.key[0].type = CSV
files.value[0] = first-file
files.key[1].path = /home/user/input2.xml
files.key[1].type = EXCEL
files.value[1] = second-file
Important
Avoid using the Map type. Instead, prefer configuring your component with an object if this is possible.

Defining Constraints and validations on the configuration

You can use metadata to specify that a field is required or has a minimum size, and so on. This is done using the validation metadata in the org.talend.sdk.component.api.configuration.constraint package:

Important
When using the programmatic API, metadata is prefixed by tcomp::. This prefix is stripped in the web for convenience, and the table above uses the web keys.

Also note that these validations are executed before the runtime is started (when loading the component instance) and that the execution will fail if they don’t pass. If it breaks your application, you can disable that validation on the JVM by setting the system property talend.component.configuration.validation.skip to true.

If you need to define a binding between properties, you can use a set of annotations:

Where:

  • target is the element to evaluate.

  • value is the value to compare against.

  • strategy (optional) is the evaluation criteria. Possible values are:

    • CONTAINS: Checks if a string or list of strings contains the defined value.

    • DEFAULT: Compares against the raw value.

    • LENGTH: For an array or string, evaluates the size of the value instead of the value itself.

  • negate (optional) defines if the test must be positive (default, set to false) or negative (set to true).

  • operator (optional) is the comparison operator used to combine several conditions, if applicable. Possible values are AND and OR.

The target element location is specified as a relative path to the current location, using Unix path characters. The configuration class delimiter is /.
The parent configuration class is specified by ...
Thus, ../targetProperty denotes a property, which is located in the parent configuration class and is named targetProperty.

Important
When using the programmatic API, metadata is prefixed with tcomp::. This prefix is stripped in the web for convenience, and the previous table uses the web keys.

For more details, refer to the related Javadocs.

ActiveIf examples

Example 1

A common use of the ActiveIf condition consists in testing if a target property has a value. To do that, it is possible to test if the length of the property value is different from 0:

  • target: foo - the path to the property to evaluate.

  • strategy: LENGTH - the strategy consists here in testing the length of the property value.

  • value: 0 - the length of the property value is compared to 0.

  • negate: true - setting negate to true means that the strategy of the target must be different from the value defined. In this case, the LENGTH of the value of the foo property must be different from 0.

{
  "condition::if::target": "foo",
  "condition::if::value": "0",
  "condition::if::negate": "true",
  "condition::if::evaluationStrategy": "LENGTH",
}

Example 2

The following example shows how to implement visibility conditions on several fields based on several checkbox configurations:

  • If the first checkbox is selected, an additional input field is displayed.

  • if the second or the third checkbox is selected, an additional input field is displayed.

  • if both second and third checkboxes are selected, an additional input field is displayed.

@GridLayout({
    // the generated layout put one configuration entry per line,
    // customize it as much as needed
    @GridLayout.Row({ "checkbox1" }),
    @GridLayout.Row({ "checkbox2" }),
    @GridLayout.Row({ "checkbox3" }),
    @GridLayout.Row({ "configuration4" }),
    @GridLayout.Row({ "configuration5" }),
    @GridLayout.Row({ "configuration6" })
})
@Documentation("A sample configuration with different visibility condition cases")
public class ActiveifProcessorProcessorConfiguration implements Serializable {
    @Option
    @Documentation("")
    private boolean checkbox1;

    @Option
    @Documentation("")
    private boolean checkbox2;

    @Option
    @Documentation("")
    private boolean checkbox3;

    @Option
    @ActiveIf(target = "checkbox1", value = "true")
    @Documentation("Active if checkbox1 is selected")
    private String configuration4;

    @Option
    @ActiveIfs(operator = ActiveIfs.Operator.OR, value = {
            @ActiveIf(target = "checkbox2", value = "true"),
            @ActiveIf(target = "checkbox3", value = "true")
    })
    @Documentation("Active if checkbox2 or checkbox 3 are selected")
    private String configuration5;

    @Option
    @ActiveIfs(operator = ActiveIfs.Operator.AND, value = {
            @ActiveIf(target = "checkbox2", value = "true"),
            @ActiveIf(target = "checkbox3", value = "true")
    })
    @Documentation("Active if checkbox2 and checkbox 3 are selected")
    private String configuration6;
  }

Adding hints about the rendering

In some cases, you may need to add metadata about the configuration to let the UI render that configuration properly.
For example, a password value that must be hidden and not a simple clear input box. For these cases - if you want to change the UI rendering - you can use a particular set of annotations:

Important
When using the programmatic API, metadata is prefixed with tcomp::. This prefix is stripped in the web for convenience, and the previous table uses the web keys.

You can also check this example about masking credentials.

Target support should cover org.talend.core.model.process.EParameterFieldType but you need to ensure that the web renderer is able to handle the same widgets.

Implementation samples

You can find sample working components for each of the configuration cases below: