YARN-8559. Expose mutable-conf scheduler's configuration in RM /scheduler-conf endpoint. Contributed by Weiwei Yang.

This commit is contained in:
Jonathan Hung 2018-08-10 15:22:11 -07:00
parent b0a364171d
commit 0420ca5a6f
6 changed files with 205 additions and 0 deletions

View File

@ -18,6 +18,7 @@
package org.apache.hadoop.yarn.server.resourcemanager.scheduler;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.yarn.webapp.dao.SchedConfUpdateInfo;
@ -58,6 +59,12 @@ public interface MutableConfigurationProvider {
*/
void confirmPendingMutation(boolean isValid) throws Exception;
/**
* Returns scheduler configuration cached in this provider.
* @return scheduler configuration.
*/
Configuration getConfiguration();
/**
* Closes the configuration provider, releasing any required resources.
* @throws IOException on failure to close

View File

@ -122,6 +122,11 @@ public class MutableCSConfigurationProvider implements CSConfigurationProvider,
return new CapacitySchedulerConfiguration(loadedConf, false);
}
@Override
public Configuration getConfiguration() {
return new Configuration(schedConf);
}
@Override
public ConfigurationMutationACLPolicy getAclMutationPolicy() {
return aclMutationPolicy;

View File

@ -188,6 +188,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ResourceInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.SchedulerInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.SchedulerTypeInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.StatisticsItemInfo;
import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ConfInfo;
import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
import org.apache.hadoop.yarn.server.utils.BuilderUtils;
import org.apache.hadoop.yarn.server.webapp.WebServices;
@ -2531,4 +2532,44 @@ public class RMWebServices extends WebServices implements RMWebServiceProtocol {
.build();
}
}
@GET
@Path("/scheduler-conf")
@Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8,
MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 })
public Response getSchedulerConfiguration(@Context HttpServletRequest hsr)
throws AuthorizationException {
init();
// Only admin user is allowed to read scheduler conf,
// in order to avoid leaking sensitive info, such as ACLs
UserGroupInformation callerUGI = getCallerUserGroupInformation(hsr, true);
ApplicationACLsManager aclsManager = rm.getApplicationACLsManager();
if (aclsManager.areACLsEnabled()) {
if (callerUGI == null || !aclsManager.isAdmin(callerUGI)) {
String msg = "Only admins can carry out this operation.";
throw new ForbiddenException(msg);
}
}
ResourceScheduler scheduler = rm.getResourceScheduler();
if (scheduler instanceof MutableConfScheduler
&& ((MutableConfScheduler) scheduler).isConfigurationMutable()) {
MutableConfigurationProvider mutableConfigurationProvider =
((MutableConfScheduler) scheduler).getMutableConfProvider();
// We load the cached configuration from configuration store,
// this should be the conf properties used by the scheduler.
Configuration schedulerConf = mutableConfigurationProvider
.getConfiguration();
return Response.status(Status.OK)
.entity(new ConfInfo(schedulerConf))
.build();
} else {
return Response.status(Status.BAD_REQUEST).entity(
"This API only supports to retrieve scheduler configuration"
+ " from a mutable-conf scheduler, underneath scheduler "
+ scheduler.getClass().getSimpleName()
+ " is not an instance of MutableConfScheduler")
.build();
}
}
}

View File

@ -0,0 +1,72 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.yarn.server.resourcemanager.webapp.dao;
import org.apache.hadoop.conf.Configuration;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
@XmlRootElement(name = "configuration")
@XmlAccessorType(XmlAccessType.FIELD)
public class ConfInfo {
protected ArrayList<ConfItem> property = new ArrayList<>();
public ConfInfo() {
} // JAXB needs this
public ConfInfo(Configuration conf) {
conf.forEach(entry ->
add(new ConfItem(entry.getKey(), entry.getValue())));
}
public void add(ConfItem confItem) {
property.add(confItem);
}
public ArrayList<ConfItem> getItems() {
return property;
}
@XmlAccessorType(XmlAccessType.FIELD)
public static class ConfItem {
private String name;
private String value;
public ConfItem() {
// JAXB needs this
}
public ConfItem(String name, String value){
this.name = name;
this.value = value;
}
public String getKey() {
return name;
}
public String getValue() {
return value;
}
}
}

View File

@ -39,6 +39,9 @@ import org.apache.hadoop.yarn.webapp.JerseyTestBase;
import org.apache.hadoop.yarn.webapp.dao.QueueConfigInfo;
import org.apache.hadoop.yarn.webapp.dao.SchedConfUpdateInfo;
import org.apache.hadoop.yarn.webapp.util.YarnWebServiceUtils;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@ -54,6 +57,7 @@ import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNotNull;
/**
* Test scheduler configuration mutation via REST API.
@ -153,8 +157,40 @@ public class TestRMWebServicesConfigurationMutation extends JerseyTestBase {
.contextPath("jersey-guice-filter").servletPath("/").build());
}
private CapacitySchedulerConfiguration getSchedulerConf()
throws JSONException {
WebResource r = resource();
ClientResponse response =
r.path("ws").path("v1").path("cluster")
.queryParam("user.name", userName).path("scheduler-conf")
.accept(MediaType.APPLICATION_JSON)
.get(ClientResponse.class);
assertEquals(Status.OK.getStatusCode(), response.getStatus());
JSONObject json = response.getEntity(JSONObject.class);
JSONArray items = (JSONArray) json.get("property");
CapacitySchedulerConfiguration parsedConf =
new CapacitySchedulerConfiguration();
for (int i=0; i<items.length(); i++) {
JSONObject obj = (JSONObject) items.get(i);
parsedConf.set(obj.get("name").toString(),
obj.get("value").toString());
}
return parsedConf;
}
@Test
public void testGetSchedulerConf() throws Exception {
CapacitySchedulerConfiguration orgConf = getSchedulerConf();
assertNotNull(orgConf);
assertEquals(3, orgConf.getQueues("root").length);
}
@Test
public void testAddNestedQueue() throws Exception {
CapacitySchedulerConfiguration orgConf = getSchedulerConf();
assertNotNull(orgConf);
assertEquals(3, orgConf.getQueues("root").length);
WebResource r = resource();
ClientResponse response;
@ -194,6 +230,10 @@ public class TestRMWebServicesConfigurationMutation extends JerseyTestBase {
0.01f);
assertEquals(75.0f, newCSConf.getNonLabeledQueueCapacity("root.d.d2"),
0.01f);
CapacitySchedulerConfiguration newConf = getSchedulerConf();
assertNotNull(newConf);
assertEquals(4, newConf.getQueues("root").length);
}
@Test

View File

@ -4445,6 +4445,7 @@ Please note that this feature is currently in the alpha stage and is subject to
### HTTP Operations Supported
* GET
* PUT
### Elements of the *sched-conf* object
@ -4456,6 +4457,45 @@ Please note that this feature is currently in the alpha stage and is subject to
| remove-queue | string | Full path name of a queue to remove |
| global-updates | map | Map of key value pairs to update scheduler's global configuration |
### GET Request Examples
Get requests are used to retrieve the scheduler's configuration that is currently loaded into scheduler's context.
**XML response**
HTTP Request:
Accept: application/xml
Content-Type: application/xml
GET http://rm-http-address:port/ws/v1/cluster/scheduler-conf
Response Header:
TTP/1.1 200 OK
Content-Type: application/xml; charset=utf-8
Transfer-Encoding: chunked
Response Body:
```xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration>
<property>
<name>yarn.scheduler.capacity.root.queues</name>
<value>default</value>
</property>
<property>
<name>yarn.scheduler.capacity.maximum-applications</name>
<value>10000</value>
</property>
<property>
<name>yarn.scheduler.capacity.root.default.capacity</name>
<value>100</value>
</property>
</configuration>
```
### PUT Request Examples
Put requests are used to modify the scheduler configuration. A successful mutation results in a 200 response. A malformed request or one which resulted in an invalid scheduler configuration results in a 400 response.