You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by sm...@apache.org on 2020/08/28 09:49:49 UTC

[knox] branch master updated: KNOX-2436 Add new service for replacing resourceManager property during Oozie usage (#369)

This is an automated email from the ASF dual-hosted git repository.

smolnar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git


The following commit(s) were added to refs/heads/master by this push:
     new bdee317  KNOX-2436 Add new service for replacing resourceManager property during Oozie usage (#369)
bdee317 is described below

commit bdee3172d8e99aa42ceeeaba6a3cee10abb51248
Author: Adam Arvai <ar...@gmail.com>
AuthorDate: Fri Aug 28 11:49:40 2020 +0200

    KNOX-2436 Add new service for replacing resourceManager property during Oozie usage (#369)
---
 .../new-desc-wizard/new-desc-wizard.component.ts   |   1 +
 .../ResourceManagerApiServiceModelGenerator.java   |  61 ++++++++++
 ...way.topology.discovery.cm.ServiceModelGenerator |   3 +-
 .../cm/ClouderaManagerServiceDiscoveryTest.java    |  11 +-
 .../gateway/config/impl/GatewayConfigImpl.java     |   3 +-
 .../gateway/config/impl/GatewayConfigImplTest.java |   6 +-
 .../resources/services/oozie/5.0.0/rewrite.xml     | 133 +++++++++++++++++++++
 .../resources/services/oozie/5.0.0/service.xml     |  57 +++++++++
 .../service/metadata/KnoxMetadataResource.java     |   2 +-
 .../ResourceManagerApiDeploymentContributor.java   |  41 +++++++
 ...nox.gateway.deploy.ServiceDeploymentContributor |   3 +-
 11 files changed, 313 insertions(+), 8 deletions(-)

diff --git a/gateway-admin-ui/admin-ui/app/new-desc-wizard/new-desc-wizard.component.ts b/gateway-admin-ui/admin-ui/app/new-desc-wizard/new-desc-wizard.component.ts
index 818dd87..453c1e8 100644
--- a/gateway-admin-ui/admin-ui/app/new-desc-wizard/new-desc-wizard.component.ts
+++ b/gateway-admin-ui/admin-ui/app/new-desc-wizard/new-desc-wizard.component.ts
@@ -62,6 +62,7 @@ export class NewDescWizardComponent implements OnInit {
         'RANGER',
         'RANGERUI',
         'RESOURCEMANAGER',
+        'RESOURCEMANAGERAPI',
         'SOLR',
         'SPARKHISTORYUI',
         'SPARK3HISTORYUI',
diff --git a/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/yarn/ResourceManagerApiServiceModelGenerator.java b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/yarn/ResourceManagerApiServiceModelGenerator.java
new file mode 100644
index 0000000..da8cbc2
--- /dev/null
+++ b/gateway-discovery-cm/src/main/java/org/apache/knox/gateway/topology/discovery/cm/model/yarn/ResourceManagerApiServiceModelGenerator.java
@@ -0,0 +1,61 @@
+/*
+ * 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.knox.gateway.topology.discovery.cm.model.yarn;
+
+import com.cloudera.api.swagger.client.ApiException;
+import com.cloudera.api.swagger.model.ApiConfigList;
+import com.cloudera.api.swagger.model.ApiRole;
+import com.cloudera.api.swagger.model.ApiService;
+import com.cloudera.api.swagger.model.ApiServiceConfig;
+import org.apache.knox.gateway.topology.discovery.cm.ServiceModel;
+
+import java.util.Locale;
+
+public class ResourceManagerApiServiceModelGenerator extends ResourceManagerServiceModelGeneratorBase {
+
+  /**
+   * The RESOURCEMANAGER service name was already taken by ResourceManagerUIServiceModelGenerator that's why we've given this the "API" postfix.
+   */
+  private static final String SERVICE = "RESOURCEMANAGERAPI";
+
+  private static final String RM_PORT = "yarn_resourcemanager_address";
+
+  @Override
+  public String getService() {
+    return SERVICE;
+  }
+
+  @Override
+  public ServiceModel.Type getModelType() {
+    return ServiceModel.Type.API;
+  }
+
+  @Override
+  public ServiceModel generateService(ApiService       service,
+                                      ApiServiceConfig serviceConfig,
+                                      ApiRole          role,
+                                      ApiConfigList    roleConfig) throws ApiException {
+
+    String hostname = role.getHostRef().getHostname();
+    String port = getRoleConfigValue(roleConfig, RM_PORT);
+
+    ServiceModel model = createServiceModel(String.format(Locale.getDefault(), "rpc://%s:%s", hostname, port));
+    model.addRoleProperty(getRoleType(), RM_PORT, port);
+
+    return model;
+  }
+}
diff --git a/gateway-discovery-cm/src/main/resources/META-INF/services/org.apache.knox.gateway.topology.discovery.cm.ServiceModelGenerator b/gateway-discovery-cm/src/main/resources/META-INF/services/org.apache.knox.gateway.topology.discovery.cm.ServiceModelGenerator
index 5c1c818..58da70a 100644
--- a/gateway-discovery-cm/src/main/resources/META-INF/services/org.apache.knox.gateway.topology.discovery.cm.ServiceModelGenerator
+++ b/gateway-discovery-cm/src/main/resources/META-INF/services/org.apache.knox.gateway.topology.discovery.cm.ServiceModelGenerator
@@ -31,7 +31,6 @@ org.apache.knox.gateway.topology.discovery.cm.model.hue.HueServiceModelGenerator
 org.apache.knox.gateway.topology.discovery.cm.model.hue.HueLBServiceModelGenerator
 org.apache.knox.gateway.topology.discovery.cm.model.impala.ImpalaServiceModelGenerator
 org.apache.knox.gateway.topology.discovery.cm.model.impala.ImpalaUIServiceModelGenerator
-org.apache.knox.gateway.topology.discovery.cm.model.yarn.JobTrackerServiceModelGenerator
 org.apache.knox.gateway.topology.discovery.cm.model.kudu.KuduUIServiceModelGenerator
 org.apache.knox.gateway.topology.discovery.cm.model.livy.LivyServiceModelGenerator
 org.apache.knox.gateway.topology.discovery.cm.model.oozie.OozieServiceModelGenerator
@@ -43,6 +42,8 @@ org.apache.knox.gateway.topology.discovery.cm.model.solr.SolrServiceModelGenerat
 org.apache.knox.gateway.topology.discovery.cm.model.spark.SparkHistoryUIServiceModelGenerator
 org.apache.knox.gateway.topology.discovery.cm.model.spark.Spark3HistoryUIServiceModelGenerator
 org.apache.knox.gateway.topology.discovery.cm.model.yarn.JobHistoryUIServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.yarn.JobTrackerServiceModelGenerator
+org.apache.knox.gateway.topology.discovery.cm.model.yarn.ResourceManagerApiServiceModelGenerator
 org.apache.knox.gateway.topology.discovery.cm.model.yarn.ResourceManagerUIServiceModelGenerator
 org.apache.knox.gateway.topology.discovery.cm.model.yarn.YarnUIServiceModelGenerator
 org.apache.knox.gateway.topology.discovery.cm.model.yarn.YarnUIv2ServiceModelGenerator
diff --git a/gateway-discovery-cm/src/test/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryTest.java b/gateway-discovery-cm/src/test/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryTest.java
index 7cdd7a5..1f947a0 100644
--- a/gateway-discovery-cm/src/test/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryTest.java
+++ b/gateway-discovery-cm/src/test/java/org/apache/knox/gateway/topology/discovery/cm/ClouderaManagerServiceDiscoveryTest.java
@@ -77,6 +77,15 @@ public class ClouderaManagerServiceDiscoveryTest {
 
   @Test
   public void testJobTrackerServiceDiscovery() {
+    doTestJobTrackerResourceManagerServiceDiscovery("JOBTRACKER");
+  }
+
+  @Test
+  public void testResourceManagerApiServiceDiscovery() {
+    doTestJobTrackerResourceManagerServiceDiscovery("RESOURCEMANAGERAPI");
+  }
+
+  private void doTestJobTrackerResourceManagerServiceDiscovery(String serviceName) {
     final String hostName = "resourcemanager-host-1";
     final String  port    = "8032";
 
@@ -94,7 +103,7 @@ public class ClouderaManagerServiceDiscoveryTest {
                                                         "RESOURCEMANAGER",
                                                         serviceProperties,
                                                         roleProperties);
-    List<String> urls = cluster.getServiceURLs("JOBTRACKER");
+    List<String> urls = cluster.getServiceURLs(serviceName);
     assertNotNull(urls);
     assertEquals(1, urls.size());
     assertEquals("rpc://" + hostName + ":" + port, urls.get(0));
diff --git a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
index 3d62237..6fe3af2 100644
--- a/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
+++ b/gateway-server/src/main/java/org/apache/knox/gateway/config/impl/GatewayConfigImpl.java
@@ -238,7 +238,8 @@ public class GatewayConfigImpl extends Configuration implements GatewayConfig {
 
   private static final List<String> DEFAULT_GLOBAL_RULES_SERVICES = Arrays.asList(
       "NAMENODE", "JOBTRACKER", "WEBHDFS", "WEBHCAT",
-      "OOZIE", "WEBHBASE", "HIVE", "RESOURCEMANAGER");
+      "OOZIE", "WEBHBASE", "HIVE", "RESOURCEMANAGER",
+      "RESOURCEMANAGERAPI");
 
   /* property that specifies list of services for which we need to append service name to the X-Forward-Context header */
   public static final String X_FORWARD_CONTEXT_HEADER_APPEND_SERVICES = GATEWAY_CONFIG_FILE_PREFIX + ".xforwarded.header.context.append.servicename";
diff --git a/gateway-server/src/test/java/org/apache/knox/gateway/config/impl/GatewayConfigImplTest.java b/gateway-server/src/test/java/org/apache/knox/gateway/config/impl/GatewayConfigImplTest.java
index 9195e1f..a9c3be6 100644
--- a/gateway-server/src/test/java/org/apache/knox/gateway/config/impl/GatewayConfigImplTest.java
+++ b/gateway-server/src/test/java/org/apache/knox/gateway/config/impl/GatewayConfigImplTest.java
@@ -173,14 +173,14 @@ public class GatewayConfigImplTest {
     list = config.getGlobalRulesServices();
     assertThat( list, is(notNullValue()) );
 
-    assertThat( list, is( CoreMatchers.hasItems("NAMENODE","JOBTRACKER", "WEBHDFS", "WEBHCAT", "OOZIE", "WEBHBASE", "HIVE", "RESOURCEMANAGER")));
+    assertThat( list, is( CoreMatchers.hasItems("NAMENODE","JOBTRACKER", "WEBHDFS", "WEBHCAT", "OOZIE", "WEBHBASE", "HIVE", "RESOURCEMANAGER", "RESOURCEMANAGERAPI")));
 
 
     config.set( GatewayConfigImpl.GLOBAL_RULES_SERVICES, "none" );
-    assertThat( config.getGlobalRulesServices(), is( CoreMatchers.hasItems("NAMENODE","JOBTRACKER", "WEBHDFS", "WEBHCAT", "OOZIE", "WEBHBASE", "HIVE", "RESOURCEMANAGER")) );
+    assertThat( config.getGlobalRulesServices(), is( CoreMatchers.hasItems("NAMENODE","JOBTRACKER", "WEBHDFS", "WEBHCAT", "OOZIE", "WEBHBASE", "HIVE", "RESOURCEMANAGER", "RESOURCEMANAGERAPI")) );
 
     config.set( GatewayConfigImpl.GLOBAL_RULES_SERVICES, "" );
-    assertThat( config.getGlobalRulesServices(), is( CoreMatchers.hasItems("NAMENODE","JOBTRACKER", "WEBHDFS", "WEBHCAT", "OOZIE", "WEBHBASE", "HIVE", "RESOURCEMANAGER")) );
+    assertThat( config.getGlobalRulesServices(), is( CoreMatchers.hasItems("NAMENODE","JOBTRACKER", "WEBHDFS", "WEBHCAT", "OOZIE", "WEBHBASE", "HIVE", "RESOURCEMANAGER", "RESOURCEMANAGERAPI")) );
 
     config.set( GatewayConfigImpl.GLOBAL_RULES_SERVICES, "ONE" );
     assertThat( config.getGlobalRulesServices(), is(hasItems("ONE")) );
diff --git a/gateway-service-definitions/src/main/resources/services/oozie/5.0.0/rewrite.xml b/gateway-service-definitions/src/main/resources/services/oozie/5.0.0/rewrite.xml
new file mode 100644
index 0000000..5e75256
--- /dev/null
+++ b/gateway-service-definitions/src/main/resources/services/oozie/5.0.0/rewrite.xml
@@ -0,0 +1,133 @@
+<!--
+   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.
+-->
+<rules>
+
+    <rule dir="IN" name="OOZIE/oozie/root" pattern="*://*:*/**/oozie/{**}?{**}">
+        <rewrite template="{$serviceUrl[OOZIE]}/{**}?{**}"/>
+    </rule>
+
+    <rule dir="IN" name="OOZIE/oozie/v1" pattern="*://*:*/**/oozie/v1/{**}?{**}">
+        <rewrite template="{$serviceUrl[OOZIE]}/v1/{**}?{**}"/>
+    </rule>
+
+    <rule dir="IN" name="OOZIE/oozie/v2" pattern="*://*:*/**/oozie/v2/{**}?{**}">
+        <rewrite template="{$serviceUrl[OOZIE]}/v2/{**}?{**}"/>
+    </rule>
+
+    <rule name="OOZIE/oozie/user-name">
+        <rewrite template="{$username}"/>
+    </rule>
+
+    <rule name="OOZIE/oozie/name-node-url">
+        <rewrite template="hdfs://{$serviceMappedAddr[NAMENODE]}"/>
+    </rule>
+
+    <rule name="OOZIE/oozie/job-tracker-address">
+        <rewrite template="{$serviceMappedAddr[JOBTRACKER]}"/>
+    </rule>
+
+    <rule name="OOZIE/oozie/resource-manager-address">
+        <rewrite template="{$serviceMappedAddr[RESOURCEMANAGERAPI]}"/>
+    </rule>
+
+    <rule name="OOZIE/oozie/hdfs-path" flow="OR">
+        <match pattern="/~">
+            <rewrite template="hdfs://{$serviceMappedAddr[NAMENODE]}/user/{$username}"/>
+        </match>
+        <match pattern="/~/{path=**}">
+            <rewrite template="hdfs://{$serviceMappedAddr[NAMENODE]}/user/{$username}/{path=**}"/>
+        </match>
+        <match pattern="{var=${*}}/{path=**}">
+            <rewrite template="{var}/{path=**}"/>
+        </match>
+        <match pattern="{path=**}">
+            <rewrite template="{$serviceMappedUrl[NAMENODE]}/{path=**}"/>
+        </match>
+    </rule>
+
+    <filter name="OOZIE/oozie/configuration">
+        <content type="*/xml">
+            <buffer path="/configuration/property">
+                <detect path="name" value="user.name">
+                    <apply path="value" rule="OOZIE/oozie/user-name"/>
+                </detect>
+                <detect path="name" value="nameNode">
+                    <apply path="value" rule="OOZIE/oozie/name-node-url"/>
+                </detect>
+                <detect path="name" value="jobTracker">
+                    <apply path="value" rule="OOZIE/oozie/job-tracker-address"/>
+                </detect>
+                <detect path="name" value="resourceManager">
+                    <apply path="value" rule="OOZIE/oozie/resource-manager-address"/>
+                </detect>
+                <detect path="name" value="fs.default.name">
+                    <apply path="value" rule="OOZIE/oozie/name-node-url"/>
+                </detect>
+                <detect path="name" value="fs.defaultFS">
+                    <apply path="value" rule="OOZIE/oozie/name-node-url"/>
+                </detect>
+                <detect path="name" value="oozie.wf.application.path">
+                    <apply path="value" rule="OOZIE/oozie/hdfs-path"/>
+                </detect>
+                <detect path="name" value="oozie.coord.application.path">
+                    <apply path="value" rule="OOZIE/oozie/hdfs-path"/>
+                </detect>
+                <detect path="name" value="oozie.bundle.application.path">
+                    <apply path="value" rule="OOZIE/oozie/hdfs-path"/>
+                </detect>
+                <detect path="name" value="oozie.libpath">
+                    <apply path="value" rule="OOZIE/oozie/hdfs-path"/>
+                </detect>
+                <detect path="name" value="mapreduce.job.user.name">
+                    <apply path="value" rule="OOZIE/oozie/user-name"/>
+                </detect>
+                <detect path="name" value="mapred.job.tracker">
+                    <apply path="value" rule="OOZIE/oozie/resource-manager-address"/>
+                </detect>
+                <detect path="name" value="mapred.input.dir">
+                    <apply path="value" rule="OOZIE/oozie/hdfs-path"/>
+                </detect>
+                <detect path="name" value="inputDir">
+                    <apply path="value" rule="OOZIE/oozie/hdfs-path"/>
+                </detect>
+                <detect path="name" value="mapred.output.dir">
+                    <apply path="value" rule="OOZIE/oozie/hdfs-path"/>
+                </detect>
+                <detect path="name" value="outputDir">
+                    <apply path="value" rule="OOZIE/oozie/hdfs-path"/>
+                </detect>
+            </buffer>
+        </content>
+        <content type="*/json">
+            <apply path="$[user.name]" rule="OOZIE/oozie/user-name"/>
+            <apply path="$[nameNode]" rule="OOZIE/oozie/name-node-url"/>
+            <apply path="$[jobTracker]" rule="OOZIE/oozie/job-tracker-address"/>
+            <apply path="$[resourceManager]" rule="OOZIE/oozie/resource-manager-address"/>
+            <apply path="$[fs.default.name]" rule="OOZIE/oozie/name-node-url"/>
+            <apply path="$[fs.defaultFS]" rule="OOZIE/oozie/name-node-url"/>
+            <apply path="$[oozie.wf.application.path]" rule="OOZIE/oozie/hdfs-path"/>
+            <apply path="$[oozie.coord.application.path]" rule="OOZIE/oozie/hdfs-path"/>
+            <apply path="$[oozie.bundle.application.path]" rule="OOZIE/oozie/hdfs-path"/>
+            <apply path="$[oozie.libpath]" rule="OOZIE/oozie/hdfs-path"/>
+            <apply path="$[mapreduce.job.user.name]" rule="OOZIE/oozie/user-name"/>
+            <apply path="$[mapred.job.tracker]" rule="OOZIE/oozie/resource-manager-address"/>
+            <apply path="$[mapred.input.dir]" rule="OOZIE/oozie/hdfs-path"/>
+            <apply path="$[mapred.output.dir]" rule="OOZIE/oozie/hdfs-path"/>
+        </content>
+    </filter>
+
+</rules>
\ No newline at end of file
diff --git a/gateway-service-definitions/src/main/resources/services/oozie/5.0.0/service.xml b/gateway-service-definitions/src/main/resources/services/oozie/5.0.0/service.xml
new file mode 100644
index 0000000..0402fac
--- /dev/null
+++ b/gateway-service-definitions/src/main/resources/services/oozie/5.0.0/service.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+   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.
+-->
+<service role="OOZIE" name="oozie" version="5.0.0">
+    <metadata>
+        <type>API</type>
+        <context>/oozie</context>
+        <shortDesc>Oozie Web Services API</shortDesc>
+        <description>Oozie is a workflow scheduler system to manage Apache Hadoop jobs. The Oozie Web Services API is a HTTP REST JSON API.</description>
+        <samples>
+            <sample>
+                <description>Fetch the supported Oozie protocol versions by the server</description>
+                <method>GET</method>
+                <path>oozie/versions</path>
+            </sample>
+             <sample>
+                <description>Fetch the system status</description>
+                <method>GET</method>
+                <path>oozie/v1/admin/status</path>
+            </sample>
+            <sample>
+                <description>You may check out Apache Oozie's REST API documentation here</description>
+                <value>https://oozie.apache.org/docs/5.2.0/WebServicesAPI.html</value>
+            </sample>
+        </samples>
+    </metadata>
+    <routes>
+        <route path="/oozie/**?**">
+            <rewrite apply="OOZIE/oozie/configuration" to="request.body"/>
+        </route>
+        <route path="/oozie/v1/**?**">
+            <rewrite apply="OOZIE/oozie/configuration" to="request.body"/>
+        </route>
+        <route path="/oozie/v2/**?**">
+            <rewrite apply="OOZIE/oozie/configuration" to="request.body"/>
+        </route>
+    </routes>
+    <testURLs>
+        <testURL>/oozie/v1/admin/build-version</testURL>
+        <testURL>/oozie/v1/admin/status</testURL>
+        <testURL>/oozie/versions</testURL>
+    </testURLs>
+</service>
diff --git a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/KnoxMetadataResource.java b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/KnoxMetadataResource.java
index 6589849..55ed0ae 100644
--- a/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/KnoxMetadataResource.java
+++ b/gateway-service-metadata/src/main/java/org/apache/knox/gateway/service/metadata/KnoxMetadataResource.java
@@ -69,7 +69,7 @@ import org.apache.knox.gateway.util.X509CertificateUtil;
 public class KnoxMetadataResource {
   private static final MetadataServiceMessages LOG = MessagesFactory.get(MetadataServiceMessages.class);
   private static final String SNAPSHOT_VERSION_POSTFIX = "-SNAPSHOT";
-  private static final Set<String> UNREAL_SERVICES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("NAMENODE", "JOBTRACKER")));
+  private static final Set<String> UNREAL_SERVICES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("NAMENODE", "JOBTRACKER", "RESOURCEMANAGERAPI")));
 
   private Set<String> pinnedTopologies;
   private java.nio.file.Path pemFilePath;
diff --git a/gateway-service-webhdfs/src/main/java/org/apache/knox/gateway/hdfs/ResourceManagerApiDeploymentContributor.java b/gateway-service-webhdfs/src/main/java/org/apache/knox/gateway/hdfs/ResourceManagerApiDeploymentContributor.java
new file mode 100644
index 0000000..6d4782c
--- /dev/null
+++ b/gateway-service-webhdfs/src/main/java/org/apache/knox/gateway/hdfs/ResourceManagerApiDeploymentContributor.java
@@ -0,0 +1,41 @@
+/*
+ * 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.knox.gateway.hdfs;
+
+import org.apache.knox.gateway.deploy.DeploymentContext;
+import org.apache.knox.gateway.deploy.ServiceDeploymentContributorBase;
+import org.apache.knox.gateway.topology.Service;
+
+public class ResourceManagerApiDeploymentContributor extends ServiceDeploymentContributorBase {
+
+  @Override
+  public String getRole() {
+    return "RESOURCEMANAGERAPI";
+  }
+
+  @Override
+  public String getName() {
+    return "resourcemanagerapi";
+  }
+
+  @Override
+  public void contributeService( DeploymentContext context, Service service ) throws Exception {
+    // NoOp
+  }
+
+}
diff --git a/gateway-service-webhdfs/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ServiceDeploymentContributor b/gateway-service-webhdfs/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ServiceDeploymentContributor
index 8907afd..bfda839 100644
--- a/gateway-service-webhdfs/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ServiceDeploymentContributor
+++ b/gateway-service-webhdfs/src/main/resources/META-INF/services/org.apache.knox.gateway.deploy.ServiceDeploymentContributor
@@ -17,4 +17,5 @@
 ##########################################################################
 
 org.apache.knox.gateway.hdfs.NameNodeDeploymentContributor
-org.apache.knox.gateway.hdfs.JobTrackerDeploymentContributor
\ No newline at end of file
+org.apache.knox.gateway.hdfs.JobTrackerDeploymentContributor
+org.apache.knox.gateway.hdfs.ResourceManagerApiDeploymentContributor
\ No newline at end of file