diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/resourceplugin/deviceframework/AssignedDevice.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/resourceplugin/deviceframework/AssignedDevice.java
new file mode 100644
index 00000000000..e3dfe5d6d25
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/resourceplugin/deviceframework/AssignedDevice.java
@@ -0,0 +1,79 @@
+/**
+ * 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.nodemanager.containermanager.resourceplugin.deviceframework;
+
+import org.apache.hadoop.yarn.api.records.ContainerId;
+import org.apache.hadoop.yarn.server.nodemanager.api.deviceplugin.Device;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * Device wrapper class used for NM REST API.
+ * */
+public class AssignedDevice implements Serializable, Comparable {
+
+ private static final long serialVersionUID = 1L;
+
+
+ Device device;
+ String containerId;
+
+ public AssignedDevice(ContainerId cId, Device dev) {
+ this.device = dev;
+ this.containerId = cId.toString();
+ }
+
+ public Device getDevice() {
+ return device;
+ }
+
+ public String getContainerId() {
+ return containerId;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ if (o == null || !(o instanceof AssignedDevice)) {
+ return -1;
+ }
+ AssignedDevice other = (AssignedDevice) o;
+ int result = getDevice().compareTo(other.getDevice());
+ if (0 != result) {
+ return result;
+ }
+ return getContainerId().compareTo(other.getContainerId());
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null || !(o instanceof AssignedDevice)) {
+ return false;
+ }
+ AssignedDevice other = (AssignedDevice) o;
+ return getDevice().equals(other.getDevice())
+ && getContainerId().equals(other.getContainerId());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getDevice(), getContainerId());
+ }
+
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/resourceplugin/deviceframework/DevicePluginAdapter.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/resourceplugin/deviceframework/DevicePluginAdapter.java
index 373f535a8dc..3bceeb7ed2a 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/resourceplugin/deviceframework/DevicePluginAdapter.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/resourceplugin/deviceframework/DevicePluginAdapter.java
@@ -20,8 +20,10 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.yarn.api.records.ContainerId;
import org.apache.hadoop.yarn.exceptions.YarnException;
import org.apache.hadoop.yarn.server.nodemanager.Context;
+import org.apache.hadoop.yarn.server.nodemanager.api.deviceplugin.Device;
import org.apache.hadoop.yarn.server.nodemanager.api.deviceplugin.DevicePlugin;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperationExecutor;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.resources.CGroupsHandler;
@@ -29,8 +31,13 @@
import org.apache.hadoop.yarn.server.nodemanager.containermanager.resourceplugin.DockerCommandPlugin;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.resourceplugin.NodeResourceUpdaterPlugin;
import org.apache.hadoop.yarn.server.nodemanager.containermanager.resourceplugin.ResourcePlugin;
+import org.apache.hadoop.yarn.server.nodemanager.webapp.dao.NMDeviceResourceInfo;
import org.apache.hadoop.yarn.server.nodemanager.webapp.dao.NMResourceInfo;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
/**
* The {@link DevicePluginAdapter} will adapt existing hooks.
@@ -96,7 +103,16 @@ public DockerCommandPlugin getDockerCommandPluginInstance() {
@Override
public NMResourceInfo getNMResourceInfo() throws YarnException {
- return null;
+ List allowed = new ArrayList<>(
+ deviceMappingManager.getAllAllowedDevices().get(resourceName));
+ List assigned = new ArrayList<>();
+ Map assignedMap =
+ deviceMappingManager.getAllUsedDevices().get(resourceName);
+ for (Map.Entry entry : assignedMap.entrySet()) {
+ assigned.add(new AssignedDevice(entry.getValue(),
+ entry.getKey()));
+ }
+ return new NMDeviceResourceInfo(allowed, assigned);
}
public DeviceResourceHandlerImpl getDeviceResourceHandler() {
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/dao/NMDeviceResourceInfo.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/dao/NMDeviceResourceInfo.java
new file mode 100644
index 00000000000..3a0ba757cae
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/webapp/dao/NMDeviceResourceInfo.java
@@ -0,0 +1,52 @@
+/**
+ * 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.nodemanager.webapp.dao;
+
+import org.apache.hadoop.yarn.server.nodemanager.api.deviceplugin.Device;
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.resourceplugin.deviceframework.AssignedDevice;
+
+import java.util.List;
+
+public class NMDeviceResourceInfo extends NMResourceInfo {
+
+ List totalDevices;
+ List assignedDevices;
+
+ public NMDeviceResourceInfo(List totalDevices, List assignedDevices) {
+ this.assignedDevices = assignedDevices;
+ this.totalDevices = totalDevices;
+ }
+
+ public List getTotalDevices() {
+ return totalDevices;
+ }
+
+ public void setTotalDevices(List totalDevices) {
+ this.totalDevices = totalDevices;
+ }
+
+ public List getAssignedDevices() {
+ return assignedDevices;
+ }
+
+ public void setAssignedDevices(
+ List assignedDevices) {
+ this.assignedDevices = assignedDevices;
+ }
+}
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/resourceplugin/deviceframework/TestDevicePluginAdapter.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/resourceplugin/deviceframework/TestDevicePluginAdapter.java
index d4638852148..a33f1871d31 100644
--- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/resourceplugin/deviceframework/TestDevicePluginAdapter.java
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/resourceplugin/deviceframework/TestDevicePluginAdapter.java
@@ -42,6 +42,8 @@
import org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerRuntimeConstants;
import org.apache.hadoop.yarn.server.nodemanager.recovery.NMMemoryStateStoreService;
import org.apache.hadoop.yarn.server.nodemanager.recovery.NMStateStoreService;
+import org.apache.hadoop.yarn.server.nodemanager.webapp.dao.NMDeviceResourceInfo;
+import org.apache.hadoop.yarn.server.nodemanager.webapp.dao.NMResourceInfo;
import org.apache.hadoop.yarn.util.resource.ResourceUtils;
import org.apache.hadoop.yarn.util.resource.TestResourceUtils;
import org.junit.After;
@@ -463,6 +465,72 @@ private static Container mockContainerWithDeviceRequest(int id,
return c;
}
+ /**
+ * Ensure correct return value generated.
+ * */
+ @Test
+ public void testNMResourceInfoRESTAPI() throws IOException, YarnException {
+ NodeManager.NMContext context = mock(NodeManager.NMContext.class);
+ NMStateStoreService storeService = mock(NMStateStoreService.class);
+ when(context.getNMStateStore()).thenReturn(storeService);
+ doNothing().when(storeService).storeAssignedResources(isA(Container.class),
+ isA(String.class),
+ isA(ArrayList.class));
+
+ // Init scheduler manager
+ DeviceMappingManager dmm = new DeviceMappingManager(context);
+
+ ResourcePluginManager rpm = mock(ResourcePluginManager.class);
+ when(rpm.getDeviceMappingManager()).thenReturn(dmm);
+
+ // Init an plugin
+ MyPlugin plugin = new MyPlugin();
+ MyPlugin spyPlugin = spy(plugin);
+ String resourceName = MyPlugin.RESOURCE_NAME;
+ // Init an adapter for the plugin
+ DevicePluginAdapter adapter = new DevicePluginAdapter(
+ resourceName,
+ spyPlugin, dmm);
+ // Bootstrap, adding device
+ adapter.initialize(context);
+ adapter.createResourceHandler(context,
+ mockCGroupsHandler, mockPrivilegedExecutor);
+ adapter.getDeviceResourceHandler().bootstrap(conf);
+ int size = dmm.getAvailableDevices(resourceName);
+ Assert.assertEquals(3, size);
+
+ // A container c1 requests 1 device
+ Container c1 = mockContainerWithDeviceRequest(0,
+ resourceName,
+ 1,false);
+ // preStart
+ adapter.getDeviceResourceHandler().preStart(c1);
+ // check book keeping
+ Assert.assertEquals(2,
+ dmm.getAvailableDevices(resourceName));
+ Assert.assertEquals(1,
+ dmm.getAllUsedDevices().get(resourceName).size());
+ Assert.assertEquals(3,
+ dmm.getAllAllowedDevices().get(resourceName).size());
+ // get REST return value
+ NMDeviceResourceInfo response =
+ (NMDeviceResourceInfo) adapter.getNMResourceInfo();
+ Assert.assertEquals(1, response.getAssignedDevices().size());
+ Assert.assertEquals(3, response.getTotalDevices().size());
+ Device device = response.getAssignedDevices().get(0).getDevice();
+ String cId = response.getAssignedDevices().get(0).getContainerId();
+ Assert.assertTrue(dmm.getAllAllowedDevices().get(resourceName)
+ .contains(device));
+ Assert.assertTrue(dmm.getAllUsedDevices().get(resourceName)
+ .containsValue(ContainerId.fromString(cId)));
+ //finish container
+ adapter.getDeviceResourceHandler().postComplete(getContainerId(0));
+ response =
+ (NMDeviceResourceInfo) adapter.getNMResourceInfo();
+ Assert.assertEquals(0, response.getAssignedDevices().size());
+ Assert.assertEquals(3, response.getTotalDevices().size());
+ }
+
private static ContainerId getContainerId(int id) {
return ContainerId.newContainerId(ApplicationAttemptId
.newInstance(ApplicationId.newInstance(1234L, 1), 1), id);