CDAP Java Client library providing programmatic APIs for interacting with the CDAP platform
—
The ArtifactClient provides comprehensive artifact lifecycle operations, plugin discovery, and application class management. Artifacts are packaged libraries that contain reusable application code and plugins for the CDAP platform.
public class ArtifactClient {
// Constructors
public ArtifactClient(ClientConfig config);
public ArtifactClient(ClientConfig config, RESTClient restClient);
// Artifact listing methods
public List<ArtifactSummary> list(NamespaceId namespace);
public List<ArtifactSummary> list(NamespaceId namespace, ArtifactScope scope);
public List<ArtifactSummary> listVersions(NamespaceId namespace, String artifactName);
public List<ArtifactSummary> listVersions(NamespaceId namespace, String artifactName, ArtifactScope scope);
// Artifact information methods
public ArtifactInfo getArtifactInfo(ArtifactId artifactId);
public ArtifactInfo getArtifactInfo(ArtifactId artifactId, ArtifactScope scope);
// Application class methods
public List<ApplicationClassSummary> getApplicationClasses(NamespaceId namespace);
public List<ApplicationClassSummary> getApplicationClasses(NamespaceId namespace, ArtifactScope scope);
public List<ApplicationClassInfo> getApplicationClasses(NamespaceId namespace, String className);
public List<ApplicationClassInfo> getApplicationClasses(NamespaceId namespace, String className, ArtifactScope scope);
// Plugin discovery methods
public List<String> getPluginTypes(ArtifactId artifactId);
public List<String> getPluginTypes(ArtifactId artifactId, ArtifactScope scope);
public List<PluginSummary> getPluginSummaries(ArtifactId artifactId, String pluginType);
public List<PluginSummary> getPluginSummaries(ArtifactId artifactId, String pluginType, ArtifactScope scope);
public List<PluginInfo> getPluginInfo(ArtifactId artifactId, String pluginType, String pluginName);
public List<PluginInfo> getPluginInfo(ArtifactId artifactId, String pluginType, String pluginName, ArtifactScope scope);
// Artifact management methods
public void add(ArtifactId artifactId, Set<ArtifactRange> parentArtifacts, ContentProvider<? extends InputStream> artifactContents);
public void add(NamespaceId namespace, String artifactName, ContentProvider<? extends InputStream> artifactContents, String artifactVersion);
public void add(NamespaceId namespace, String artifactName, ContentProvider<? extends InputStream> artifactContents, String artifactVersion, Set<ArtifactRange> parentArtifacts);
public void add(NamespaceId namespace, String artifactName, ContentProvider<? extends InputStream> artifactContents, String artifactVersion, Set<ArtifactRange> parentArtifacts, Set<PluginClass> additionalPlugins);
public void delete(ArtifactId artifactId);
// Property management methods
public void writeProperties(ArtifactId artifactId, Map<String, String> properties);
public void deleteProperties(ArtifactId artifactId);
public void writeProperty(ArtifactId artifactId, String key, String value);
public void deleteProperty(ArtifactId artifactId, String key);
}public class ArtifactSummary {
public String getName();
public String getVersion();
public ArtifactScope getScope();
public String getDescription();
public String getAuthor();
public long getCreationTimeMillis();
}
public class ArtifactInfo {
public String getName();
public String getVersion();
public ArtifactScope getScope();
public String getDescription();
public String getAuthor();
public long getCreationTimeMillis();
public List<String> getClasses();
public Map<String, PluginClass> getPlugins();
public Set<ArtifactRange> getParents();
public Map<String, String> getProperties();
}
public class ArtifactId {
public static ArtifactId of(NamespaceId namespace, String name, String version);
public NamespaceId getNamespace();
public String getName();
public String getVersion();
}
public enum ArtifactScope {
USER, SYSTEM
}
public class ArtifactRange {
public ArtifactRange(NamespaceId namespace, String name, String lowerVersion, boolean lowerInclusive, String upperVersion, boolean upperInclusive);
public NamespaceId getNamespace();
public String getName();
public String getLowerVersion();
public String getUpperVersion();
public boolean isLowerInclusive();
public boolean isUpperInclusive();
}// List all artifacts in namespace
List<ArtifactSummary> allArtifacts = artifactClient.list(namespace);
System.out.println("Found " + allArtifacts.size() + " artifacts");
for (ArtifactSummary artifact : allArtifacts) {
System.out.println("- " + artifact.getName() + " v" + artifact.getVersion());
System.out.println(" Scope: " + artifact.getScope());
System.out.println(" Author: " + artifact.getAuthor());
System.out.println(" Description: " + artifact.getDescription());
}
// List artifacts by scope
List<ArtifactSummary> userArtifacts = artifactClient.list(namespace, ArtifactScope.USER);
List<ArtifactSummary> systemArtifacts = artifactClient.list(namespace, ArtifactScope.SYSTEM);// List all versions of a specific artifact
String artifactName = "data-pipeline";
List<ArtifactSummary> versions = artifactClient.listVersions(namespace, artifactName);
System.out.println("Versions of " + artifactName + ":");
for (ArtifactSummary version : versions) {
System.out.println("- v" + version.getVersion() + " (" + version.getScope() + ")");
}
// List versions with scope filter
List<ArtifactSummary> userVersions = artifactClient.listVersions(
namespace,
artifactName,
ArtifactScope.USER
);// Get detailed artifact information
ArtifactId artifactId = ArtifactId.of(namespace, "data-pipeline", "1.2.0");
ArtifactInfo info = artifactClient.getArtifactInfo(artifactId);
System.out.println("Artifact: " + info.getName() + " v" + info.getVersion());
System.out.println("Classes: " + info.getClasses());
System.out.println("Plugin types: " + info.getPlugins().keySet());
System.out.println("Parent artifacts: " + info.getParents());
System.out.println("Properties: " + info.getProperties());// Get all plugin types available in artifact
List<String> pluginTypes = artifactClient.getPluginTypes(artifactId);
System.out.println("Available plugin types: " + pluginTypes);
// Plugin types with scope
List<String> userPluginTypes = artifactClient.getPluginTypes(artifactId, ArtifactScope.USER);// Get all plugins of a specific type
String pluginType = "source";
List<PluginSummary> plugins = artifactClient.getPluginSummaries(artifactId, pluginType);
System.out.println("Available " + pluginType + " plugins:");
for (PluginSummary plugin : plugins) {
System.out.println("- " + plugin.getName());
System.out.println(" Description: " + plugin.getDescription());
System.out.println(" Type: " + plugin.getType());
}
// Get detailed information about specific plugin
String pluginName = "Database";
List<PluginInfo> pluginInfos = artifactClient.getPluginInfo(artifactId, pluginType, pluginName);
for (PluginInfo pluginInfo : pluginInfos) {
System.out.println("Plugin: " + pluginInfo.getName());
System.out.println("Class: " + pluginInfo.getClassName());
System.out.println("Config schema: " + pluginInfo.getConfigSchema());
System.out.println("Properties: " + pluginInfo.getProperties());
}// Get all application classes available in namespace
List<ApplicationClassSummary> allClasses = artifactClient.getApplicationClasses(namespace);
for (ApplicationClassSummary classInfo : allClasses) {
System.out.println("Class: " + classInfo.getClassName());
System.out.println("Description: " + classInfo.getDescription());
}
// Get application classes by scope
List<ApplicationClassSummary> userClasses = artifactClient.getApplicationClasses(
namespace,
ArtifactScope.USER
);
// Get specific application class information
String className = "io.cdap.cdap.etl.batch.BatchApplication";
List<ApplicationClassInfo> classInfos = artifactClient.getApplicationClasses(namespace, className);
for (ApplicationClassInfo classInfo : classInfos) {
System.out.println("Class: " + classInfo.getClassName());
System.out.println("Config schema: " + classInfo.getConfigSchema());
System.out.println("Available in artifacts: " + classInfo.getArtifactSummaries());
}// Basic artifact addition
File artifactJar = new File("/path/to/my-artifact.jar");
ContentProvider<InputStream> content = ContentProviders.of(artifactJar);
String artifactName = "my-custom-artifact";
String version = "1.0.0";
artifactClient.add(namespace, artifactName, content, version);
// Add artifact with parent dependencies
ArtifactRange parentRange = new ArtifactRange(
NamespaceId.SYSTEM,
"cdap-data-pipeline",
"6.0.0", true, // lower version inclusive
"7.0.0", false // upper version exclusive
);
Set<ArtifactRange> parents = Set.of(parentRange);
ArtifactId newArtifactId = ArtifactId.of(namespace, artifactName, version);
artifactClient.add(newArtifactId, parents, content);
// Add artifact with additional plugins
Set<PluginClass> additionalPlugins = Set.of(
new PluginClass("source", "CustomSource", "Custom data source plugin",
"com.company.CustomSource", "custom-source-config",
Map.of("endpoint", "string"))
);
artifactClient.add(namespace, artifactName, content, version, parents, additionalPlugins);// Set multiple properties
Map<String, String> properties = Map.of(
"author", "Data Team",
"maintainer", "data-team@company.com",
"documentation", "https://docs.company.com/artifacts/my-artifact",
"category", "data-processing"
);
artifactClient.writeProperties(artifactId, properties);
// Set individual property
artifactClient.writeProperty(artifactId, "last-updated", "2023-12-01");
// Remove individual property
artifactClient.deleteProperty(artifactId, "deprecated-property");
// Remove all properties
artifactClient.deleteProperties(artifactId);// Delete artifact (will fail if applications depend on it)
try {
artifactClient.delete(artifactId);
System.out.println("Artifact deleted successfully");
} catch (ArtifactInUseException e) {
System.err.println("Cannot delete artifact - applications depend on it: " + e.getMessage());
} catch (ArtifactNotFoundException e) {
System.err.println("Artifact not found: " + artifactId);
}// Discover plugin configuration requirements
ArtifactId pipelineArtifact = ArtifactId.of(NamespaceId.SYSTEM, "cdap-data-pipeline", "6.11.0");
List<String> pluginTypes = artifactClient.getPluginTypes(pipelineArtifact);
for (String type : pluginTypes) {
System.out.println("Plugin type: " + type);
List<PluginSummary> plugins = artifactClient.getPluginSummaries(pipelineArtifact, type);
for (PluginSummary plugin : plugins) {
System.out.println(" Plugin: " + plugin.getName());
// Get detailed configuration schema
List<PluginInfo> infos = artifactClient.getPluginInfo(pipelineArtifact, type, plugin.getName());
for (PluginInfo info : infos) {
System.out.println(" Class: " + info.getClassName());
System.out.println(" Config Schema: " + info.getConfigSchema());
System.out.println(" Endpoints: " + info.getEndpoints());
}
}
}// Find all artifacts that provide a specific plugin type
String targetPluginType = "transform";
List<ArtifactSummary> allArtifacts = artifactClient.list(namespace, ArtifactScope.USER);
for (ArtifactSummary artifact : allArtifacts) {
ArtifactId id = ArtifactId.of(namespace, artifact.getName(), artifact.getVersion());
try {
List<String> types = artifactClient.getPluginTypes(id);
if (types.contains(targetPluginType)) {
System.out.println("Artifact " + artifact.getName() + " provides " + targetPluginType + " plugins");
List<PluginSummary> plugins = artifactClient.getPluginSummaries(id, targetPluginType);
for (PluginSummary plugin : plugins) {
System.out.println(" - " + plugin.getName());
}
}
} catch (Exception e) {
System.err.println("Error checking artifact " + artifact.getName() + ": " + e.getMessage());
}
}Artifact operations may throw these exceptions:
try {
ArtifactInfo info = artifactClient.getArtifactInfo(artifactId);
System.out.println("Artifact info: " + info.getName());
} catch (ArtifactNotFoundException e) {
System.err.println("Artifact not found: " + artifactId);
} catch (UnauthorizedException e) {
System.err.println("No permission to access artifact: " + e.getMessage());
} catch (IOException e) {
System.err.println("Network error: " + e.getMessage());
}// Good: Semantic versioning and proper scoping
ArtifactId customArtifact = ArtifactId.of(
NamespaceId.of("development"),
"company-data-transforms",
"2.1.0" // Semantic version
);
// Good: Comprehensive artifact addition with metadata
Map<String, String> metadata = Map.of(
"author", "Data Engineering Team",
"documentation", "https://wiki.company.com/data-transforms",
"support-contact", "data-team@company.com",
"build-timestamp", Instant.now().toString()
);
// Add the artifact
artifactClient.add(customArtifact, parentDependencies, jarContent);
// Set metadata
artifactClient.writeProperties(customArtifact, metadata);
// Good: Plugin discovery with caching
Map<ArtifactId, List<String>> pluginCache = new HashMap<>();
List<String> getPluginTypesWithCache(ArtifactId id) {
return pluginCache.computeIfAbsent(id,
artifactId -> {
try {
return artifactClient.getPluginTypes(artifactId);
} catch (Exception e) {
System.err.println("Error getting plugin types for " + artifactId + ": " + e.getMessage());
return List.of();
}
}
);
}Install with Tessl CLI
npx tessl i tessl/maven-io-cdap-cdap--cdap-client