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.