2626
2727import javax .ws .rs .core .MediaType ;
2828
29+ import com .google .common .base .Preconditions ;
2930import org .apache .commons .lang .StringUtils ;
3031import org .apache .hadoop .conf .Configuration ;
3132import org .apache .hadoop .fs .FileSystem ;
4041import org .apache .hadoop .yarn .conf .YarnConfiguration ;
4142import org .apache .hadoop .yarn .exceptions .YarnException ;
4243import 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 ;
4346import org .apache .hadoop .yarn .service .api .records .Service ;
4447import org .apache .hadoop .yarn .service .api .records .ServiceState ;
4548import 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 ;
4651import org .apache .hadoop .yarn .service .utils .ServiceApiUtil ;
4752import org .apache .hadoop .yarn .util .RMHAUtils ;
53+ import org .codehaus .jackson .map .PropertyNamingStrategy ;
4854import org .eclipse .jetty .util .UrlEncoded ;
4955import org .slf4j .Logger ;
5056import 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