CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-cdap-cdap--cdap-client

CDAP Java Client library providing programmatic APIs for interacting with the CDAP platform

Pending
Overview
Eval results
Files

artifact-management.mddocs/

Artifact Management

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.

ArtifactClient

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);
}

Artifact Types and Information

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();
}

Artifact Listing and Discovery

Basic Artifact Listing

// 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);

Artifact Version Management

// 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
);

Detailed Artifact Information

// 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());

Plugin Discovery

Plugin Type Discovery

// 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);

Plugin Listing and Information

// 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());
}

Application Class Management

Application Class Discovery

// 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());
}

Artifact Management

Add New Artifacts

// 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);

Property Management

// 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);

Artifact Deletion

// 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);
}

Advanced Plugin Discovery

Plugin Configuration Analysis

// 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());
        }
    }
}

Cross-Artifact Plugin Search

// 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());
    }
}

Error Handling

Artifact operations may throw these exceptions:

  • ArtifactNotFoundException: Artifact does not exist
  • ArtifactAlreadyExistsException: Artifact already exists during addition
  • ArtifactInUseException: Cannot delete artifact - applications depend on it
  • InvalidArtifactException: Invalid artifact format or content
  • PluginNotFoundException: Requested plugin not found
  • UnauthenticatedException: Authentication required
  • UnauthorizedException: Insufficient permissions
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());
}

Best Practices

  1. Versioning: Use semantic versioning for artifacts
  2. Dependencies: Carefully manage parent artifact relationships
  3. Scope Management: Use USER scope for custom artifacts, SYSTEM for platform artifacts
  4. Plugin Discovery: Cache plugin information to avoid repeated API calls
  5. Property Management: Use properties for artifact metadata and documentation links
  6. Testing: Test artifacts thoroughly before deploying to production namespaces
// 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

docs

application-management.md

artifact-management.md

configuration.md

data-operations.md

dataset-operations.md

index.md

metrics-monitoring.md

program-control.md

schedule-management.md

security-administration.md

service-management.md

tile.json