As seen in the Getting Started, you need an annotation to register
your component through family method. Multiple components can use the same family value but the pair family+name
MUST be unique for the system.
If you desire (recommended) to share the same component family name instead of repeating yourself in all family methods,
you can use @Components annotation on the root package of you component, it will enable you to define the component family and
the categories the component belongs to (default is Misc if not set). Here is a sample package-info.java:
@Components(name = "my_component_family", categories = "My Category")
package org.talend.sdk.component.sample;
import org.talend.sdk.component.api.component.Components;
For an existing component it can look like:
@Components(name = "Salesforce", categories = {"Business", "Cloud"})
package org.talend.sdk.component.sample;
import org.talend.sdk.component.api.component.Components;
Components metadata
Components can require a few metadata to be integrated in Talend Studio or Cloud platform. Here is how to provide these information.
These metadata are set on the component class and belongs to org.talend.sdk.component.api.component package.
| API | Description |
|---|---|
@Icon |
Set an icon key used to represent the component. Note you can use a custom key with |
@Version |
Set the component version, default to 1. |
Example:
@Icon(FILE_XML_O)
@PartitionMapper(name = "jaxbInput")
public class JaxbPartitionMapper implements Serializable {
// ...
}
Management of configuration versions
If some impacting changes happen on the configuration they can be manage through a migration handler at component level (to enable to support trans-model migration).
The @Version annotation supports a migrationHandler method which will take the implementation migrating the incoming configuration
to the current model.
For instance if filepath configuration entry from v1 changed to location in v2 you can remap the value to the right key in your
MigrationHandler implementation.
| it is recommended to not manage all migrations in the handler but rather split it in services you inject in the migration handler (through constructor): |
// full component code structure skipped for brievity, kept only migration part
@Version(value = 3, migrationHandler = MyComponent.Migrations.class)
public class MyComponent {
// the component code...
private interface VersionConfigurationHandler {
Map<String, String> migrate(Map<String, String> incomingData);
}
public static class Migrations {
private final List<VersionConfigurationHandler> handlers;
// VersionConfigurationHandler implementations are decorated with @Service
public Migrations(final List<VersionConfigurationHandler> migrations) {
this.handlers = migrations;
this.handlers.sort(/*some custom logic*/);
}
@Override
public Map<String, String> migrate(int incomingVersion, Map<String, String> incomingData) {
Map<String, String> out = incomingData;
for (MigrationHandler handler : handlers) {
out = handler.migrate(out);
}
}
}
}
What is important in this snippet is not much the way the code is organized but rather the fact you organize your migrations the way which fits the best
your component. If migrations are not conflicting no need of something fancy, just apply them all but if you need to apply them in order
you need to ensure they are sorted. Said otherwise: don’t see this API as a migration API but as a migration callback
and adjust the migration code structure you need behind the MigrationHandler based on your
component requirements. The service injection enables you to do so.