0
# Application Management
1
2
The ApplicationClient provides comprehensive application lifecycle management including deployment, updating, deletion, versioning, and program management. Applications are the primary deployment units in CDAP that contain one or more programs.
3
4
## ApplicationClient
5
6
```java { .api }
7
public class ApplicationClient {
8
// Constructors
9
public ApplicationClient(ClientConfig config);
10
public ApplicationClient(ClientConfig config, RESTClient restClient);
11
12
// Application listing methods
13
public List<ApplicationRecord> list(NamespaceId namespace);
14
public JsonObject paginatedList(NamespaceId namespace, String nextPageToken);
15
public List<ApplicationRecord> list(NamespaceId namespace, String artifactName, String artifactVersion, Boolean latestOnly);
16
public List<ApplicationRecord> list(NamespaceId namespace, Set<String> artifactNames, String artifactVersion, Boolean latestOnly);
17
public List<String> listAppVersions(NamespaceId namespace, String appName);
18
19
// Application details methods
20
public ApplicationDetail get(ApplicationId appId);
21
public ApplicationDetail get(ApplicationId appId, boolean latestOnly);
22
public List<PluginInstanceDetail> getPlugins(ApplicationId appId);
23
public boolean exists(ApplicationId app);
24
25
// Application lifecycle methods
26
public void deploy(NamespaceId namespace, File jarFile);
27
public void deploy(NamespaceId namespace, File jarFile, String appConfig);
28
public void deploy(NamespaceId namespace, File jarFile, String appConfig, String ownerPrincipal);
29
public void deploy(NamespaceId namespace, File jarFile, Config appConfig);
30
public void deploy(ApplicationId appId, AppRequest<?> createRequest);
31
public void update(ApplicationId appId, AppRequest<?> updateRequest);
32
public void upgradeApplication(ApplicationId app);
33
public void upgradeApplication(ApplicationId app, Set<String> artifactScopes, boolean allowSnapshot);
34
public void delete(ApplicationId app);
35
public void deleteApp(ApplicationId app);
36
public void deleteAll(NamespaceId namespace);
37
38
// Program management methods
39
public List<ProgramRecord> listAllPrograms(NamespaceId namespace, ProgramType programType);
40
public Map<ProgramType, List<ProgramRecord>> listAllPrograms(NamespaceId namespace);
41
public List<ProgramRecord> listPrograms(ApplicationId app, ProgramType programType);
42
public Map<ProgramType, List<ProgramRecord>> listProgramsByType(ApplicationId app);
43
public List<ProgramRecord> listPrograms(ApplicationId app);
44
45
// Schedule management methods
46
public void addSchedule(ApplicationId app, ScheduleDetail scheduleDetail);
47
public void enableSchedule(ScheduleId scheduleId);
48
49
// Utility methods
50
public void waitForDeployed(ApplicationId app, long timeout, TimeUnit timeoutUnit);
51
public void waitForDeleted(ApplicationId app, long timeout, TimeUnit timeoutUnit);
52
}
53
```
54
55
## Application Types and Records
56
57
```java { .api }
58
public class ApplicationRecord {
59
public String getName();
60
public String getAppVersion();
61
public String getDescription();
62
public ArtifactSummary getArtifact();
63
public String getOwnerPrincipal();
64
public long getCreationTimeMillis();
65
}
66
67
public class ApplicationDetail {
68
public String getName();
69
public String getAppVersion();
70
public String getDescription();
71
public ApplicationSpecification getSpec();
72
public ArtifactSummary getArtifact();
73
public String getOwnerPrincipal();
74
public long getCreationTimeMillis();
75
public Map<String, String> getConfiguration();
76
}
77
78
public class PluginInstanceDetail {
79
public String getName();
80
public String getType();
81
public ArtifactSummary getArtifact();
82
public Map<String, String> getProperties();
83
}
84
85
public class AppRequest<T> {
86
public AppRequest(ArtifactSummary artifact);
87
public AppRequest(ArtifactSummary artifact, T config);
88
public ArtifactSummary getArtifact();
89
public T getConfig();
90
}
91
```
92
93
## Application Listing and Discovery
94
95
### Basic Listing
96
97
```java
98
// List all applications in default namespace
99
NamespaceId namespace = NamespaceId.DEFAULT;
100
List<ApplicationRecord> apps = appClient.list(namespace);
101
102
System.out.println("Found " + apps.size() + " applications:");
103
for (ApplicationRecord app : apps) {
104
System.out.println("- " + app.getName() + " v" + app.getAppVersion());
105
System.out.println(" Artifact: " + app.getArtifact().getName() + " v" + app.getArtifact().getVersion());
106
System.out.println(" Owner: " + app.getOwnerPrincipal());
107
}
108
```
109
110
### Paginated Listing
111
112
```java
113
// Get paginated list of applications
114
String nextPageToken = null;
115
do {
116
JsonObject page = appClient.paginatedList(namespace, nextPageToken);
117
JsonArray applications = page.getAsJsonArray("applications");
118
119
for (JsonElement appElement : applications) {
120
JsonObject app = appElement.getAsJsonObject();
121
System.out.println("App: " + app.get("name").getAsString());
122
}
123
124
nextPageToken = page.has("nextPageToken") ?
125
page.get("nextPageToken").getAsString() : null;
126
} while (nextPageToken != null);
127
```
128
129
### Filtered Listing
130
131
```java
132
// List applications by artifact
133
List<ApplicationRecord> sparkApps = appClient.list(
134
namespace,
135
"cdap-spark", // artifact name
136
"1.0.0", // artifact version
137
true // latest only
138
);
139
140
// List applications by multiple artifacts
141
Set<String> artifactNames = Set.of("cdap-spark", "cdap-mapreduce");
142
List<ApplicationRecord> dataApps = appClient.list(
143
namespace,
144
artifactNames,
145
"1.0.0",
146
false // all versions
147
);
148
149
// List all versions of a specific application
150
String appName = "my-analytics-app";
151
List<String> versions = appClient.listAppVersions(namespace, appName);
152
System.out.println("Versions of " + appName + ": " + versions);
153
```
154
155
## Application Details and Inspection
156
157
```java
158
// Get detailed application information
159
ApplicationId appId = ApplicationId.of(namespace, "my-app", "1.0.0");
160
ApplicationDetail detail = appClient.get(appId);
161
162
System.out.println("Application: " + detail.getName());
163
System.out.println("Version: " + detail.getAppVersion());
164
System.out.println("Description: " + detail.getDescription());
165
System.out.println("Artifact: " + detail.getArtifact().getName());
166
System.out.println("Configuration: " + detail.getConfiguration());
167
168
// Get application specification
169
ApplicationSpecification spec = detail.getSpec();
170
System.out.println("Programs: " + spec.getPrograms().keySet());
171
System.out.println("Datasets: " + spec.getDatasets().keySet());
172
173
// Get plugins used by the application
174
List<PluginInstanceDetail> plugins = appClient.getPlugins(appId);
175
for (PluginInstanceDetail plugin : plugins) {
176
System.out.println("Plugin: " + plugin.getName() + " (type: " + plugin.getType() + ")");
177
System.out.println(" Artifact: " + plugin.getArtifact().getName());
178
System.out.println(" Properties: " + plugin.getProperties());
179
}
180
181
// Check if application exists
182
boolean exists = appClient.exists(appId);
183
if (exists) {
184
System.out.println("Application exists");
185
}
186
```
187
188
## Application Deployment
189
190
### Deploy from JAR File
191
192
```java
193
// Basic deployment from JAR file
194
File jarFile = new File("/path/to/my-app.jar");
195
appClient.deploy(namespace, jarFile);
196
197
// Deploy with configuration
198
String appConfig = "{\"config.key\": \"config.value\"}";
199
appClient.deploy(namespace, jarFile, appConfig);
200
201
// Deploy with configuration and owner
202
String owner = "data-team@company.com";
203
appClient.deploy(namespace, jarFile, appConfig, owner);
204
205
// Deploy with Config object
206
Config configObj = new MyAppConfig("value1", "value2");
207
appClient.deploy(namespace, jarFile, configObj);
208
```
209
210
### Deploy from Artifact
211
212
```java
213
// Create application from existing artifact
214
ArtifactSummary artifact = new ArtifactSummary("my-artifact", "1.0.0", ArtifactScope.USER);
215
AppRequest<Map<String, String>> createRequest = new AppRequest<>(artifact);
216
217
ApplicationId newAppId = ApplicationId.of(namespace, "my-new-app", "1.0.0");
218
appClient.deploy(newAppId, createRequest);
219
220
// Deploy with configuration
221
Map<String, String> config = Map.of(
222
"input.path", "/data/input",
223
"output.path", "/data/output",
224
"batch.size", "1000"
225
);
226
AppRequest<Map<String, String>> configuredRequest = new AppRequest<>(artifact, config);
227
appClient.deploy(newAppId, configuredRequest);
228
```
229
230
### Deployment with Wait
231
232
```java
233
// Deploy and wait for completion
234
appClient.deploy(namespace, jarFile);
235
appClient.waitForDeployed(newAppId, 60, TimeUnit.SECONDS);
236
System.out.println("Application deployed successfully");
237
```
238
239
## Application Updates and Upgrades
240
241
### Update Application Configuration
242
243
```java
244
// Update existing application with new configuration
245
Map<String, String> newConfig = Map.of(
246
"updated.parameter", "new-value",
247
"batch.size", "2000"
248
);
249
250
ArtifactSummary currentArtifact = new ArtifactSummary("my-artifact", "1.0.0", ArtifactScope.USER);
251
AppRequest<Map<String, String>> updateRequest = new AppRequest<>(currentArtifact, newConfig);
252
253
appClient.update(appId, updateRequest);
254
```
255
256
### Upgrade to Latest Artifact
257
258
```java
259
// Upgrade application to latest compatible artifact version
260
appClient.upgradeApplication(appId);
261
262
// Upgrade with specific options
263
Set<String> scopes = Set.of("USER", "SYSTEM");
264
boolean allowSnapshot = true;
265
appClient.upgradeApplication(appId, scopes, allowSnapshot);
266
```
267
268
## Application Deletion
269
270
```java
271
// Delete specific application version
272
appClient.delete(appId);
273
274
// Delete all versions of an application
275
ApplicationId allVersionsId = ApplicationId.of(namespace, "my-app");
276
appClient.deleteApp(allVersionsId);
277
278
// Delete all applications in namespace (use with caution!)
279
appClient.deleteAll(namespace);
280
281
// Delete with wait confirmation
282
appClient.delete(appId);
283
appClient.waitForDeleted(appId, 30, TimeUnit.SECONDS);
284
System.out.println("Application deleted successfully");
285
```
286
287
## Program Management
288
289
### List Programs
290
291
```java
292
// List all programs in an application
293
List<ProgramRecord> allPrograms = appClient.listPrograms(appId);
294
for (ProgramRecord program : allPrograms) {
295
System.out.println("Program: " + program.getName() + " (type: " + program.getType() + ")");
296
}
297
298
// List programs by type
299
List<ProgramRecord> workflows = appClient.listPrograms(appId, ProgramType.WORKFLOW);
300
List<ProgramRecord> services = appClient.listPrograms(appId, ProgramType.SERVICE);
301
302
// List programs grouped by type
303
Map<ProgramType, List<ProgramRecord>> programsByType = appClient.listProgramsByType(appId);
304
for (Map.Entry<ProgramType, List<ProgramRecord>> entry : programsByType.entrySet()) {
305
System.out.println(entry.getKey() + " programs: " + entry.getValue().size());
306
}
307
308
// List all programs of a specific type across all applications in namespace
309
List<ProgramRecord> allServices = appClient.listAllPrograms(namespace, ProgramType.SERVICE);
310
311
// List all programs across all applications in namespace
312
Map<ProgramType, List<ProgramRecord>> allPrograms = appClient.listAllPrograms(namespace);
313
```
314
315
## Schedule Management
316
317
```java
318
// Add schedule to application
319
ScheduleDetail scheduleDetail = ScheduleDetail.builder()
320
.setName("daily-schedule")
321
.setDescription("Run daily at midnight")
322
.setTrigger(new TimeTrigger("0 0 * * *")) // Cron expression
323
.setProgram(ProgramId.of(appId, ProgramType.WORKFLOW, "data-processing"))
324
.build();
325
326
appClient.addSchedule(appId, scheduleDetail);
327
328
// Enable the schedule
329
ScheduleId scheduleId = ScheduleId.of(appId, "daily-schedule");
330
appClient.enableSchedule(scheduleId);
331
```
332
333
## Error Handling
334
335
Application management operations may throw these exceptions:
336
337
- **ApplicationNotFoundException**: Application does not exist
338
- **ApplicationAlreadyExistsException**: Application already exists during deployment
339
- **ArtifactNotFoundException**: Referenced artifact does not exist
340
- **InvalidApplicationException**: Invalid application configuration or structure
341
- **UnauthenticatedException**: Authentication required
342
- **UnauthorizedException**: Insufficient permissions
343
344
```java
345
try {
346
ApplicationDetail detail = appClient.get(appId);
347
System.out.println("Application found: " + detail.getName());
348
} catch (ApplicationNotFoundException e) {
349
System.err.println("Application not found: " + appId);
350
} catch (UnauthorizedException e) {
351
System.err.println("No permission to access application: " + e.getMessage());
352
} catch (IOException e) {
353
System.err.println("Network error: " + e.getMessage());
354
}
355
```
356
357
## Best Practices
358
359
1. **Version Management**: Always specify application versions for production deployments
360
2. **Configuration Management**: Use external configuration files rather than hardcoding values
361
3. **Gradual Rollouts**: Test applications in development namespaces before production
362
4. **Cleanup**: Regularly clean up old application versions to save storage
363
5. **Monitoring**: Monitor application deployment status and handle failures gracefully
364
6. **Backup**: Keep backup copies of application JAR files and configurations
365
366
```java
367
// Good: Explicit version management
368
ApplicationId prodApp = ApplicationId.of(
369
NamespaceId.of("production"),
370
"analytics-app",
371
"2.1.0"
372
);
373
374
// Good: Configuration from external source
375
Properties config = loadConfigFromFile("app-config.properties");
376
Map<String, String> appConfig = config.entrySet().stream()
377
.collect(Collectors.toMap(
378
e -> (String) e.getKey(),
379
e -> (String) e.getValue()
380
));
381
382
// Good: Error handling with retry logic
383
int maxRetries = 3;
384
for (int i = 0; i < maxRetries; i++) {
385
try {
386
appClient.deploy(namespace, jarFile, appConfig);
387
System.out.println("Deployment successful");
388
break;
389
} catch (IOException e) {
390
if (i == maxRetries - 1) {
391
throw new RuntimeException("Deployment failed after " + maxRetries + " attempts", e);
392
}
393
System.out.println("Deployment attempt " + (i + 1) + " failed, retrying...");
394
Thread.sleep(5000); // Wait 5 seconds before retry
395
}
396
}
397
```