Skip to content

Commit 86ae380

Browse files
committed
YARN-7939. Added support to upgrade a component instance.
Contributed by Chandni Singh
1 parent 583a2f4 commit 86ae380

File tree

41 files changed

+1961
-287
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1961
-287
lines changed

hadoop-yarn-project/hadoop-yarn/hadoop-yarn-applications/hadoop-yarn-services-api/src/main/java/org/apache/hadoop/yarn/service/client/ApiServiceClient.java

Lines changed: 71 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import javax.ws.rs.core.MediaType;
2828

29+
import com.google.common.base.Preconditions;
2930
import org.apache.commons.lang.StringUtils;
3031
import org.apache.hadoop.conf.Configuration;
3132
import org.apache.hadoop.fs.FileSystem;
@@ -40,11 +41,16 @@
4041
import org.apache.hadoop.yarn.conf.YarnConfiguration;
4142
import org.apache.hadoop.yarn.exceptions.YarnException;
4243
import org.apache.hadoop.yarn.service.api.records.Component;
44+
import org.apache.hadoop.yarn.service.api.records.Container;
45+
import org.apache.hadoop.yarn.service.api.records.ContainerState;
4346
import org.apache.hadoop.yarn.service.api.records.Service;
4447
import org.apache.hadoop.yarn.service.api.records.ServiceState;
4548
import org.apache.hadoop.yarn.service.api.records.ServiceStatus;
49+
import org.apache.hadoop.yarn.service.conf.RestApiConstants;
50+
import org.apache.hadoop.yarn.service.utils.JsonSerDeser;
4651
import org.apache.hadoop.yarn.service.utils.ServiceApiUtil;
4752
import org.apache.hadoop.yarn.util.RMHAUtils;
53+
import org.codehaus.jackson.map.PropertyNamingStrategy;
4854
import org.eclipse.jetty.util.UrlEncoded;
4955
import org.slf4j.Logger;
5056
import org.slf4j.LoggerFactory;
@@ -131,7 +137,7 @@ private String getRMWebAddress() {
131137
* @return URI to API Service
132138
* @throws IOException
133139
*/
134-
private String getApiUrl(String appName) throws IOException {
140+
private String getServicePath(String appName) throws IOException {
135141
String url = getRMWebAddress();
136142
StringBuilder api = new StringBuilder();
137143
api.append(url);
@@ -148,23 +154,40 @@ private String getApiUrl(String appName) throws IOException {
148154
return api.toString();
149155
}
150156

157+
private String getInstancesPath(String appName) throws IOException {
158+
Preconditions.checkNotNull(appName);
159+
String url = getRMWebAddress();
160+
StringBuilder api = new StringBuilder();
161+
api.append(url);
162+
api.append("/app/v1/services/").append(appName).append("/")
163+
.append(RestApiConstants.COMP_INSTANCES);
164+
Configuration conf = getConfig();
165+
if (conf.get("hadoop.http.authentication.type").equalsIgnoreCase(
166+
"simple")) {
167+
api.append("?user.name=" + UrlEncoded
168+
.encodeString(System.getProperty("user.name")));
169+
}
170+
return api.toString();
171+
}
172+
151173
private Builder getApiClient() throws IOException {
152-
return getApiClient(null);
174+
return getApiClient(getServicePath(null));
153175
}
154176

155177
/**
156178
* Setup API service web request.
157179
*
158-
* @param appName
180+
* @param requestPath
159181
* @return
160182
* @throws IOException
161183
*/
162-
private Builder getApiClient(String appName) throws IOException {
184+
private Builder getApiClient(String requestPath)
185+
throws IOException {
163186
Client client = Client.create(getClientConfig());
164187
Configuration conf = getConfig();
165188
client.setChunkedEncodingSize(null);
166189
Builder builder = client
167-
.resource(getApiUrl(appName)).type(MediaType.APPLICATION_JSON);
190+
.resource(requestPath).type(MediaType.APPLICATION_JSON);
168191
if (conf.get("hadoop.http.authentication.type").equals("kerberos")) {
169192
AuthenticatedURL.Token token = new AuthenticatedURL.Token();
170193
builder.header("WWW-Authenticate", token);
@@ -312,7 +335,7 @@ public int actionStop(String appName) throws IOException, YarnException {
312335
service.setName(appName);
313336
service.setState(ServiceState.STOPPED);
314337
String buffer = jsonSerDeser.toJson(service);
315-
ClientResponse response = getApiClient(appName)
338+
ClientResponse response = getApiClient(getServicePath(appName))
316339
.put(ClientResponse.class, buffer);
317340
result = processResponse(response);
318341
} catch (Exception e) {
@@ -335,7 +358,7 @@ public int actionStart(String appName) throws IOException, YarnException {
335358
service.setName(appName);
336359
service.setState(ServiceState.STARTED);
337360
String buffer = jsonSerDeser.toJson(service);
338-
ClientResponse response = getApiClient(appName)
361+
ClientResponse response = getApiClient(getServicePath(appName))
339362
.put(ClientResponse.class, buffer);
340363
result = processResponse(response);
341364
} catch (Exception e) {
@@ -381,7 +404,7 @@ public int actionSave(String fileName, String appName, Long lifetime,
381404
public int actionDestroy(String appName) throws IOException, YarnException {
382405
int result = EXIT_SUCCESS;
383406
try {
384-
ClientResponse response = getApiClient(appName)
407+
ClientResponse response = getApiClient(getServicePath(appName))
385408
.delete(ClientResponse.class);
386409
result = processResponse(response);
387410
} catch (Exception e) {
@@ -413,7 +436,7 @@ public int actionFlex(String appName, Map<String, String> componentCounts)
413436
service.addComponent(component);
414437
}
415438
String buffer = jsonSerDeser.toJson(service);
416-
ClientResponse response = getApiClient(appName)
439+
ClientResponse response = getApiClient(getServicePath(appName))
417440
.put(ClientResponse.class, buffer);
418441
result = processResponse(response);
419442
} catch (Exception e) {
@@ -454,7 +477,8 @@ public String getStatusString(String appIdOrName) throws IOException,
454477
ServiceApiUtil.validateNameFormat(appName, getConfig());
455478
}
456479
try {
457-
ClientResponse response = getApiClient(appName).get(ClientResponse.class);
480+
ClientResponse response = getApiClient(getServicePath(appName))
481+
.get(ClientResponse.class);
458482
if (response.getStatus() != 200) {
459483
StringBuilder sb = new StringBuilder();
460484
sb.append(appName);
@@ -470,21 +494,53 @@ public String getStatusString(String appIdOrName) throws IOException,
470494
}
471495

472496
@Override
473-
public int actionUpgrade(String appName,
474-
String fileName) throws IOException, YarnException {
497+
public int initiateUpgrade(String appName,
498+
String fileName, boolean autoFinalize) throws IOException, YarnException {
475499
int result;
476500
try {
477501
Service service =
478502
loadAppJsonFromLocalFS(fileName, appName, null, null);
479-
service.setState(ServiceState.UPGRADING);
503+
if (autoFinalize) {
504+
service.setState(ServiceState.UPGRADING_AUTO_FINALIZE);
505+
} else {
506+
service.setState(ServiceState.UPGRADING);
507+
}
480508
String buffer = jsonSerDeser.toJson(service);
481-
ClientResponse response = getApiClient()
482-
.post(ClientResponse.class, buffer);
509+
ClientResponse response = getApiClient(getServicePath(appName))
510+
.put(ClientResponse.class, buffer);
483511
result = processResponse(response);
484512
} catch (Exception e) {
485513
LOG.error("Failed to upgrade application: ", e);
486514
result = EXIT_EXCEPTION_THROWN;
487515
}
488516
return result;
489517
}
518+
519+
@Override
520+
public int actionUpgradeInstances(String appName, List<String> compInstances)
521+
throws IOException, YarnException {
522+
int result;
523+
Container[] toUpgrade = new Container[compInstances.size()];
524+
try {
525+
int idx = 0;
526+
for (String instanceName : compInstances) {
527+
Container container = new Container();
528+
container.setComponentInstanceName(instanceName);
529+
container.setState(ContainerState.UPGRADING);
530+
toUpgrade[idx++] = container;
531+
}
532+
String buffer = containerJsonSerde.toJson(toUpgrade);
533+
ClientResponse response = getApiClient(getInstancesPath(appName))
534+
.put(ClientResponse.class, buffer);
535+
result = processResponse(response);
536+
} catch (Exception e) {
537+
LOG.error("Failed to upgrade component instance: ", e);
538+
result = EXIT_EXCEPTION_THROWN;
539+
}
540+
return result;
541+
}
542+
543+
private static JsonSerDeser<Container[]> containerJsonSerde =
544+
new JsonSerDeser<>(Container[].class,
545+
PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
490546
}

0 commit comments

Comments
 (0)