Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
@Plugin(type = "runnable")
@Name("noop")
public class NoOpRunnable implements Runnable {

  public abstract void run() {
    // do nothing
  }
}

A program can register a plugin at configure time (application creation time) by specifying the plugin type, name, properties, and assigning an id to the plugin:

Code Block
public class ExampleWorker extends AbstractWorker {

  @Override
  public void configure() {
    usePlugin("runnable", "noop", "id", PluginProperties.builder().build());
  }
}

Once registered, the plugin can be instantiated and used at runtime using the plugin id it was registered with:

Code Block
public class ExampleWorker extends AbstractWorker {
  private Runnable runnable;

  @Override
  public void configure() {
    usePlugin("runnable", "noop", "id", PluginProperties.builder().build());
  }

  @Override
  public void initialize(WorkerContext context) throws Exception {
    runnable = context.newPluginInstance("id");
  }

  @Override
  public void run() {
    runnable.run();
  }
}

Plugin Config

Plugin can also make use of the PluginConfig class to configure itself. Suppose we want to modify our no-op runnable to print a configurable message. We can do this by adding a PluginConfig, passing it into the constructor, and setting it as a field:

Code Block
@Plugin(type = "runnable")
@Name("noop")
public class NoOpRunnable implements Runnable {
  private final Conf conf;

  public static class Conf extends PluginConfig {
    @Nullable
    @Macro
    private String message;

    public Conf() {
      this.message = "Hello World!";
    }
  }

  public NoOpRunnable(Conf conf) {
    this.conf = conf;
  }

  public abstract void run() {
    System.out.println(conf.message);
  }
}

Your extension to PluginConfig must contain only primitive, boxed primitive, or String types. The PluginConfig passed in to the Plugin has its fields populated using the PluginProperties specified when the Plugin was registered. In this example, if we want the message to be "Hello CDAP!":

...

  • The @Nullable annotation tells CDAP that the field is not required. Without that annotation, CDAP will complain if no plugin property for delimiter is given.

  • Configuration fields can be annotated with an @Description that will be returned by the Artifact HTTP RESTful API Plugin Detail.

  • The @Macro annotation makes the field message macro-enabled; this allows the value of the field message to be a "macro key" whose value will be set at runtime.

...

Code Block
{
  "parents": [ "system:cdap-data-pipeline[6.2.0,6.2.0]", "system:cdap-data-streams[6.2.0,6.2.0]" ],
  "plugins": [
    {
      "name": "mysql",
      "type": "jdbc",
      "className": "com.mysql.jdbc.Driver"
    }
  ]
}

Using the CLI:

Code Block
cdap > describe artifact properties custom-transforms 1.0.0 [system | user]

Plugin Deployment

To make plugins available to another artifact (and thus available to any application created from one of the artifacts), the plugins must first be packaged in a JAR file. After that, the JAR file must be deployed either as system artifact or a user artifacta system artifact or a user artifact.

A system artifact is available to users across any namespace. A user artifact is available only to users in the namespace to which it is deployed. By design, deploying as a user artifact just requires access to the Artifact the Artifact HTTP RESTful API, while deploying as a system artifact requires access to the filesystem of the CDAP Master. This then requires administrator access and permission.

...

Code Block
{
  "parents": [ "cdap-data-pipeline[3.5.0,4.0.0)", "cdap-data-streams[3.5.0,4.0.0)" ]
}

specifies that these plugins can be used by versions 3.5.0 (inclusive) to 4.0.0 (exclusive) of the cdap-data-pipeline and cdap-data-streams artifacts.

...

Once your JARs and matching configuration files are in place, a CDAP CLI command (load artifact) or a HTTP RESTful API call to load to load system artifacts can artifacts can be made to load the artifacts. As described in the documentation on Artifacts, only snapshot artifacts can be re-deployed without requiring that they first be deleted.

...

To deploy the artifact as a user artifact, use the Artifact the Artifact HTTP RESTful API API Add Artifact or the CLI.

When using the HTTP RESTful API, you will need to specify the Artifact-Extends header. Unless the artifact's version is defined in the manifest file of the JAR file you upload, you will also need to specify the Artifact-Version header.

When using the CLI, a configuration file exactly like the one described in the Deploying the “Deploying as a System Artifact must Artifact” must be used.

For example, to deploy custom-transforms-1.0.0.jar using the RESTful API:

...

You can deploy third-party JARs in the same way except the plugin information needs to needs to be explicitly listed. As described in the documentation on Artifactson Artifacts, only snapshot artifacts can be re-deployed without requiring that they first be deleted.

...

You can verify that a plugin artifact was added successfully by using the Artifact the Artifact HTTP RESTful API to API to retrieve artifact details. For example, to retrieve detail about our custom-transforms artifact:

...

You can verify that the plugins in your newly-added artifact are available to its parent by using the Artifact the Artifact HTTP RESTful API to API to list plugins of a specific type. For example, to check if cdap-data-pipeline can access the plugins in the custom-transforms artifact:

...