0
# Artifact Management
1
2
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.
3
4
## ArtifactClient
5
6
```java { .api }
7
public class ArtifactClient {
8
// Constructors
9
public ArtifactClient(ClientConfig config);
10
public ArtifactClient(ClientConfig config, RESTClient restClient);
11
12
// Artifact listing methods
13
public List<ArtifactSummary> list(NamespaceId namespace);
14
public List<ArtifactSummary> list(NamespaceId namespace, ArtifactScope scope);
15
public List<ArtifactSummary> listVersions(NamespaceId namespace, String artifactName);
16
public List<ArtifactSummary> listVersions(NamespaceId namespace, String artifactName, ArtifactScope scope);
17
18
// Artifact information methods
19
public ArtifactInfo getArtifactInfo(ArtifactId artifactId);
20
public ArtifactInfo getArtifactInfo(ArtifactId artifactId, ArtifactScope scope);
21
22
// Application class methods
23
public List<ApplicationClassSummary> getApplicationClasses(NamespaceId namespace);
24
public List<ApplicationClassSummary> getApplicationClasses(NamespaceId namespace, ArtifactScope scope);
25
public List<ApplicationClassInfo> getApplicationClasses(NamespaceId namespace, String className);
26
public List<ApplicationClassInfo> getApplicationClasses(NamespaceId namespace, String className, ArtifactScope scope);
27
28
// Plugin discovery methods
29
public List<String> getPluginTypes(ArtifactId artifactId);
30
public List<String> getPluginTypes(ArtifactId artifactId, ArtifactScope scope);
31
public List<PluginSummary> getPluginSummaries(ArtifactId artifactId, String pluginType);
32
public List<PluginSummary> getPluginSummaries(ArtifactId artifactId, String pluginType, ArtifactScope scope);
33
public List<PluginInfo> getPluginInfo(ArtifactId artifactId, String pluginType, String pluginName);
34
public List<PluginInfo> getPluginInfo(ArtifactId artifactId, String pluginType, String pluginName, ArtifactScope scope);
35
36
// Artifact management methods
37
public void add(ArtifactId artifactId, Set<ArtifactRange> parentArtifacts, ContentProvider<? extends InputStream> artifactContents);
38
public void add(NamespaceId namespace, String artifactName, ContentProvider<? extends InputStream> artifactContents, String artifactVersion);
39
public void add(NamespaceId namespace, String artifactName, ContentProvider<? extends InputStream> artifactContents, String artifactVersion, Set<ArtifactRange> parentArtifacts);
40
public void add(NamespaceId namespace, String artifactName, ContentProvider<? extends InputStream> artifactContents, String artifactVersion, Set<ArtifactRange> parentArtifacts, Set<PluginClass> additionalPlugins);
41
public void delete(ArtifactId artifactId);
42
43
// Property management methods
44
public void writeProperties(ArtifactId artifactId, Map<String, String> properties);
45
public void deleteProperties(ArtifactId artifactId);
46
public void writeProperty(ArtifactId artifactId, String key, String value);
47
public void deleteProperty(ArtifactId artifactId, String key);
48
}
49
```
50
51
## Artifact Types and Information
52
53
```java { .api }
54
public class ArtifactSummary {
55
public String getName();
56
public String getVersion();
57
public ArtifactScope getScope();
58
public String getDescription();
59
public String getAuthor();
60
public long getCreationTimeMillis();
61
}
62
63
public class ArtifactInfo {
64
public String getName();
65
public String getVersion();
66
public ArtifactScope getScope();
67
public String getDescription();
68
public String getAuthor();
69
public long getCreationTimeMillis();
70
public List<String> getClasses();
71
public Map<String, PluginClass> getPlugins();
72
public Set<ArtifactRange> getParents();
73
public Map<String, String> getProperties();
74
}
75
76
public class ArtifactId {
77
public static ArtifactId of(NamespaceId namespace, String name, String version);
78
public NamespaceId getNamespace();
79
public String getName();
80
public String getVersion();
81
}
82
83
public enum ArtifactScope {
84
USER, SYSTEM
85
}
86
87
public class ArtifactRange {
88
public ArtifactRange(NamespaceId namespace, String name, String lowerVersion, boolean lowerInclusive, String upperVersion, boolean upperInclusive);
89
public NamespaceId getNamespace();
90
public String getName();
91
public String getLowerVersion();
92
public String getUpperVersion();
93
public boolean isLowerInclusive();
94
public boolean isUpperInclusive();
95
}
96
```
97
98
## Artifact Listing and Discovery
99
100
### Basic Artifact Listing
101
102
```java
103
// List all artifacts in namespace
104
List<ArtifactSummary> allArtifacts = artifactClient.list(namespace);
105
System.out.println("Found " + allArtifacts.size() + " artifacts");
106
107
for (ArtifactSummary artifact : allArtifacts) {
108
System.out.println("- " + artifact.getName() + " v" + artifact.getVersion());
109
System.out.println(" Scope: " + artifact.getScope());
110
System.out.println(" Author: " + artifact.getAuthor());
111
System.out.println(" Description: " + artifact.getDescription());
112
}
113
114
// List artifacts by scope
115
List<ArtifactSummary> userArtifacts = artifactClient.list(namespace, ArtifactScope.USER);
116
List<ArtifactSummary> systemArtifacts = artifactClient.list(namespace, ArtifactScope.SYSTEM);
117
```
118
119
### Artifact Version Management
120
121
```java
122
// List all versions of a specific artifact
123
String artifactName = "data-pipeline";
124
List<ArtifactSummary> versions = artifactClient.listVersions(namespace, artifactName);
125
126
System.out.println("Versions of " + artifactName + ":");
127
for (ArtifactSummary version : versions) {
128
System.out.println("- v" + version.getVersion() + " (" + version.getScope() + ")");
129
}
130
131
// List versions with scope filter
132
List<ArtifactSummary> userVersions = artifactClient.listVersions(
133
namespace,
134
artifactName,
135
ArtifactScope.USER
136
);
137
```
138
139
### Detailed Artifact Information
140
141
```java
142
// Get detailed artifact information
143
ArtifactId artifactId = ArtifactId.of(namespace, "data-pipeline", "1.2.0");
144
ArtifactInfo info = artifactClient.getArtifactInfo(artifactId);
145
146
System.out.println("Artifact: " + info.getName() + " v" + info.getVersion());
147
System.out.println("Classes: " + info.getClasses());
148
System.out.println("Plugin types: " + info.getPlugins().keySet());
149
System.out.println("Parent artifacts: " + info.getParents());
150
System.out.println("Properties: " + info.getProperties());
151
```
152
153
## Plugin Discovery
154
155
### Plugin Type Discovery
156
157
```java
158
// Get all plugin types available in artifact
159
List<String> pluginTypes = artifactClient.getPluginTypes(artifactId);
160
System.out.println("Available plugin types: " + pluginTypes);
161
162
// Plugin types with scope
163
List<String> userPluginTypes = artifactClient.getPluginTypes(artifactId, ArtifactScope.USER);
164
```
165
166
### Plugin Listing and Information
167
168
```java
169
// Get all plugins of a specific type
170
String pluginType = "source";
171
List<PluginSummary> plugins = artifactClient.getPluginSummaries(artifactId, pluginType);
172
173
System.out.println("Available " + pluginType + " plugins:");
174
for (PluginSummary plugin : plugins) {
175
System.out.println("- " + plugin.getName());
176
System.out.println(" Description: " + plugin.getDescription());
177
System.out.println(" Type: " + plugin.getType());
178
}
179
180
// Get detailed information about specific plugin
181
String pluginName = "Database";
182
List<PluginInfo> pluginInfos = artifactClient.getPluginInfo(artifactId, pluginType, pluginName);
183
184
for (PluginInfo pluginInfo : pluginInfos) {
185
System.out.println("Plugin: " + pluginInfo.getName());
186
System.out.println("Class: " + pluginInfo.getClassName());
187
System.out.println("Config schema: " + pluginInfo.getConfigSchema());
188
System.out.println("Properties: " + pluginInfo.getProperties());
189
}
190
```
191
192
## Application Class Management
193
194
### Application Class Discovery
195
196
```java
197
// Get all application classes available in namespace
198
List<ApplicationClassSummary> allClasses = artifactClient.getApplicationClasses(namespace);
199
200
for (ApplicationClassSummary classInfo : allClasses) {
201
System.out.println("Class: " + classInfo.getClassName());
202
System.out.println("Description: " + classInfo.getDescription());
203
}
204
205
// Get application classes by scope
206
List<ApplicationClassSummary> userClasses = artifactClient.getApplicationClasses(
207
namespace,
208
ArtifactScope.USER
209
);
210
211
// Get specific application class information
212
String className = "io.cdap.cdap.etl.batch.BatchApplication";
213
List<ApplicationClassInfo> classInfos = artifactClient.getApplicationClasses(namespace, className);
214
215
for (ApplicationClassInfo classInfo : classInfos) {
216
System.out.println("Class: " + classInfo.getClassName());
217
System.out.println("Config schema: " + classInfo.getConfigSchema());
218
System.out.println("Available in artifacts: " + classInfo.getArtifactSummaries());
219
}
220
```
221
222
## Artifact Management
223
224
### Add New Artifacts
225
226
```java
227
// Basic artifact addition
228
File artifactJar = new File("/path/to/my-artifact.jar");
229
ContentProvider<InputStream> content = ContentProviders.of(artifactJar);
230
String artifactName = "my-custom-artifact";
231
String version = "1.0.0";
232
233
artifactClient.add(namespace, artifactName, content, version);
234
235
// Add artifact with parent dependencies
236
ArtifactRange parentRange = new ArtifactRange(
237
NamespaceId.SYSTEM,
238
"cdap-data-pipeline",
239
"6.0.0", true, // lower version inclusive
240
"7.0.0", false // upper version exclusive
241
);
242
Set<ArtifactRange> parents = Set.of(parentRange);
243
244
ArtifactId newArtifactId = ArtifactId.of(namespace, artifactName, version);
245
artifactClient.add(newArtifactId, parents, content);
246
247
// Add artifact with additional plugins
248
Set<PluginClass> additionalPlugins = Set.of(
249
new PluginClass("source", "CustomSource", "Custom data source plugin",
250
"com.company.CustomSource", "custom-source-config",
251
Map.of("endpoint", "string"))
252
);
253
254
artifactClient.add(namespace, artifactName, content, version, parents, additionalPlugins);
255
```
256
257
### Property Management
258
259
```java
260
// Set multiple properties
261
Map<String, String> properties = Map.of(
262
"author", "Data Team",
263
"maintainer", "data-team@company.com",
264
"documentation", "https://docs.company.com/artifacts/my-artifact",
265
"category", "data-processing"
266
);
267
artifactClient.writeProperties(artifactId, properties);
268
269
// Set individual property
270
artifactClient.writeProperty(artifactId, "last-updated", "2023-12-01");
271
272
// Remove individual property
273
artifactClient.deleteProperty(artifactId, "deprecated-property");
274
275
// Remove all properties
276
artifactClient.deleteProperties(artifactId);
277
```
278
279
### Artifact Deletion
280
281
```java
282
// Delete artifact (will fail if applications depend on it)
283
try {
284
artifactClient.delete(artifactId);
285
System.out.println("Artifact deleted successfully");
286
} catch (ArtifactInUseException e) {
287
System.err.println("Cannot delete artifact - applications depend on it: " + e.getMessage());
288
} catch (ArtifactNotFoundException e) {
289
System.err.println("Artifact not found: " + artifactId);
290
}
291
```
292
293
## Advanced Plugin Discovery
294
295
### Plugin Configuration Analysis
296
297
```java
298
// Discover plugin configuration requirements
299
ArtifactId pipelineArtifact = ArtifactId.of(NamespaceId.SYSTEM, "cdap-data-pipeline", "6.11.0");
300
List<String> pluginTypes = artifactClient.getPluginTypes(pipelineArtifact);
301
302
for (String type : pluginTypes) {
303
System.out.println("Plugin type: " + type);
304
305
List<PluginSummary> plugins = artifactClient.getPluginSummaries(pipelineArtifact, type);
306
for (PluginSummary plugin : plugins) {
307
System.out.println(" Plugin: " + plugin.getName());
308
309
// Get detailed configuration schema
310
List<PluginInfo> infos = artifactClient.getPluginInfo(pipelineArtifact, type, plugin.getName());
311
for (PluginInfo info : infos) {
312
System.out.println(" Class: " + info.getClassName());
313
System.out.println(" Config Schema: " + info.getConfigSchema());
314
System.out.println(" Endpoints: " + info.getEndpoints());
315
}
316
}
317
}
318
```
319
320
### Cross-Artifact Plugin Search
321
322
```java
323
// Find all artifacts that provide a specific plugin type
324
String targetPluginType = "transform";
325
List<ArtifactSummary> allArtifacts = artifactClient.list(namespace, ArtifactScope.USER);
326
327
for (ArtifactSummary artifact : allArtifacts) {
328
ArtifactId id = ArtifactId.of(namespace, artifact.getName(), artifact.getVersion());
329
try {
330
List<String> types = artifactClient.getPluginTypes(id);
331
if (types.contains(targetPluginType)) {
332
System.out.println("Artifact " + artifact.getName() + " provides " + targetPluginType + " plugins");
333
334
List<PluginSummary> plugins = artifactClient.getPluginSummaries(id, targetPluginType);
335
for (PluginSummary plugin : plugins) {
336
System.out.println(" - " + plugin.getName());
337
}
338
}
339
} catch (Exception e) {
340
System.err.println("Error checking artifact " + artifact.getName() + ": " + e.getMessage());
341
}
342
}
343
```
344
345
## Error Handling
346
347
Artifact operations may throw these exceptions:
348
349
- **ArtifactNotFoundException**: Artifact does not exist
350
- **ArtifactAlreadyExistsException**: Artifact already exists during addition
351
- **ArtifactInUseException**: Cannot delete artifact - applications depend on it
352
- **InvalidArtifactException**: Invalid artifact format or content
353
- **PluginNotFoundException**: Requested plugin not found
354
- **UnauthenticatedException**: Authentication required
355
- **UnauthorizedException**: Insufficient permissions
356
357
```java
358
try {
359
ArtifactInfo info = artifactClient.getArtifactInfo(artifactId);
360
System.out.println("Artifact info: " + info.getName());
361
} catch (ArtifactNotFoundException e) {
362
System.err.println("Artifact not found: " + artifactId);
363
} catch (UnauthorizedException e) {
364
System.err.println("No permission to access artifact: " + e.getMessage());
365
} catch (IOException e) {
366
System.err.println("Network error: " + e.getMessage());
367
}
368
```
369
370
## Best Practices
371
372
1. **Versioning**: Use semantic versioning for artifacts
373
2. **Dependencies**: Carefully manage parent artifact relationships
374
3. **Scope Management**: Use USER scope for custom artifacts, SYSTEM for platform artifacts
375
4. **Plugin Discovery**: Cache plugin information to avoid repeated API calls
376
5. **Property Management**: Use properties for artifact metadata and documentation links
377
6. **Testing**: Test artifacts thoroughly before deploying to production namespaces
378
379
```java
380
// Good: Semantic versioning and proper scoping
381
ArtifactId customArtifact = ArtifactId.of(
382
NamespaceId.of("development"),
383
"company-data-transforms",
384
"2.1.0" // Semantic version
385
);
386
387
// Good: Comprehensive artifact addition with metadata
388
Map<String, String> metadata = Map.of(
389
"author", "Data Engineering Team",
390
"documentation", "https://wiki.company.com/data-transforms",
391
"support-contact", "data-team@company.com",
392
"build-timestamp", Instant.now().toString()
393
);
394
395
// Add the artifact
396
artifactClient.add(customArtifact, parentDependencies, jarContent);
397
// Set metadata
398
artifactClient.writeProperties(customArtifact, metadata);
399
400
// Good: Plugin discovery with caching
401
Map<ArtifactId, List<String>> pluginCache = new HashMap<>();
402
List<String> getPluginTypesWithCache(ArtifactId id) {
403
return pluginCache.computeIfAbsent(id,
404
artifactId -> {
405
try {
406
return artifactClient.getPluginTypes(artifactId);
407
} catch (Exception e) {
408
System.err.println("Error getting plugin types for " + artifactId + ": " + e.getMessage());
409
return List.of();
410
}
411
}
412
);
413
}
414
```