You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@knox.apache.org by km...@apache.org on 2014/07/17 23:19:27 UTC

[6/6] git commit: KNOX-74: Support YARN REST API access via the Gateway

KNOX-74: Support YARN REST API access via the Gateway


Project: http://git-wip-us.apache.org/repos/asf/knox/repo
Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/a970502a
Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/a970502a
Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/a970502a

Branch: refs/heads/master
Commit: a970502aaea2ae5f97bf1e3834431f9856b7a36f
Parents: 66bc41a
Author: Kevin Minder <ke...@hortonworks.com>
Authored: Thu Jul 17 17:19:05 2014 -0400
Committer: Kevin Minder <ke...@hortonworks.com>
Committed: Thu Jul 17 17:19:05 2014 -0400

----------------------------------------------------------------------
 .../pom.xml                                     |  111 +
 .../encrypturi/EncryptStepContextParams.java    |   47 +
 .../encrypturi/api/DecryptUriDescriptor.java    |   39 +
 .../encrypturi/api/EncryptUriDescriptor.java    |   49 +
 .../encrypturi/impl/DecryptUriProcessor.java    |   89 +
 .../impl/EncryptUriDeploymentContributor.java   |   79 +
 .../encrypturi/impl/EncryptUriProcessor.java    |   85 +
 ...gateway.deploy.ProviderDeploymentContributor |   19 +
 ....filter.rewrite.api.UrlRewriteStepDescriptor |   20 +
 ...y.filter.rewrite.spi.UrlRewriteStepProcessor |   20 +
 .../api/DecryptUriDescriptorTest.java           |   55 +
 .../api/EncryptUriDescriptorTest.java           |   55 +
 .../impl/EncryptDecryptUriProcessorTest.java    |  157 +
 .../EncryptUriDeploymentContributorTest.java    |  105 +
 .../UrlRewriteActionRewriteProcessorExt.java    |    6 +-
 .../filter/rewrite/spi/UrlRewriteContext.java   |    4 +
 .../home/conf/topologies/sandbox.xml            |    5 +
 gateway-release/pom.xml                         |    8 +
 gateway-service-yarn-rm/pom.xml                 |   61 +
 .../ResourceManagerDeploymentContributor.java   |  150 +
 ....gateway.deploy.ServiceDeploymentContributor |   19 +
 .../rewrite.xml                                 |  193 +
 ...esourceManagerDeploymentContributorTest.java |   45 +
 .../org/apache/hadoop/gateway/shell/Shell.java  |    1 +
 .../hadoop/gateway/shell/yarn/AppState.java     |   69 +
 .../gateway/shell/yarn/ExampleYarnApp.groovy    |   87 +
 .../hadoop/gateway/shell/yarn/KillApp.java      |   68 +
 .../hadoop/gateway/shell/yarn/NewApp.java       |   62 +
 .../hadoop/gateway/shell/yarn/SubmitApp.java    |   81 +
 .../apache/hadoop/gateway/shell/yarn/Yarn.java  |   42 +
 .../hadoop/gateway/GatewayBasicFuncTest.java    |  723 ++-
 .../GatewayBasicFuncTest/yarn/app_running.json  |   25 +
 .../GatewayBasicFuncTest/yarn/app_running.xml   |   40 +
 .../yarn/app_succeeded.json                     |   25 +
 .../GatewayBasicFuncTest/yarn/app_succeeded.xml |   40 +
 .../GatewayBasicFuncTest/yarn/appattempts.json  |   14 +
 .../GatewayBasicFuncTest/yarn/appattempts.xml   |   27 +
 .../yarn/application-killing.json               |    1 +
 .../yarn/application-submit-request.json        |   49 +
 .../gateway/GatewayBasicFuncTest/yarn/apps.json |   72 +
 .../gateway/GatewayBasicFuncTest/yarn/apps.xml  |   85 +
 .../yarn/appstatistics.json                     |   26 +
 .../GatewayBasicFuncTest/yarn/appstatistics.xml |   39 +
 .../GatewayBasicFuncTest/yarn/cluster-info.json |   14 +
 .../GatewayBasicFuncTest/yarn/cluster-info.xml  |   34 +
 .../yarn/cluster-metrics.json                   |   23 +
 .../yarn/cluster-metrics.xml                    |   38 +
 .../yarn/new-application.json                   |    1 +
 .../gateway/GatewayBasicFuncTest/yarn/node.json |   15 +
 .../gateway/GatewayBasicFuncTest/yarn/node.xml  |   30 +
 .../GatewayBasicFuncTest/yarn/nodes.json        |   19 +
 .../gateway/GatewayBasicFuncTest/yarn/nodes.xml |   32 +
 .../yarn/proxy-mapreduce-info.json              |    9 +
 .../yarn/proxy-mapreduce-info.xml               |   24 +
 .../yarn/proxy-mapreduce-job-attempts.json      |   14 +
 .../yarn/proxy-mapreduce-job-attempts.xml       |   27 +
 .../yarn/proxy-mapreduce-job-conf.json          | 5263 ++++++++++++++++++
 .../yarn/proxy-mapreduce-job-conf.xml           | 4019 +++++++++++++
 .../yarn/proxy-mapreduce-job-counters.json      |  307 +
 .../yarn/proxy-mapreduce-job-counters.xml       |  313 ++
 .../yarn/proxy-mapreduce-job.json               |   33 +
 .../yarn/proxy-mapreduce-job.xml                |   48 +
 .../yarn/proxy-mapreduce-jobs.json              |   37 +
 .../yarn/proxy-mapreduce-jobs.xml               |   50 +
 .../proxy-mapreduce-task-attempt-counters.json  |  155 +
 .../proxy-mapreduce-task-attempt-counters.xml   |  163 +
 .../yarn/proxy-mapreduce-task-attempt.json      |   21 +
 .../yarn/proxy-mapreduce-task-attempt.xml       |   37 +
 .../yarn/proxy-mapreduce-task-attempts.json     |   26 +
 .../yarn/proxy-mapreduce-task-attempts.xml      |   40 +
 .../yarn/proxy-mapreduce-task-counters.json     |  155 +
 .../yarn/proxy-mapreduce-task-counters.xml      |  160 +
 .../yarn/proxy-mapreduce-task.json              |   13 +
 .../yarn/proxy-mapreduce-task.xml               |   28 +
 .../yarn/proxy-mapreduce-tasks.json             |   28 +
 .../yarn/proxy-mapreduce-tasks.xml              |   42 +
 .../GatewayBasicFuncTest/yarn/scheduler.json    |   41 +
 .../GatewayBasicFuncTest/yarn/scheduler.xml     |   53 +
 hsso-release/pom.xml                            |    8 +
 pom.xml                                         |   12 +
 80 files changed, 14324 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite-step-encrypt-uri/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-encrypt-uri/pom.xml b/gateway-provider-rewrite-step-encrypt-uri/pom.xml
new file mode 100644
index 0000000..e2f1f35
--- /dev/null
+++ b/gateway-provider-rewrite-step-encrypt-uri/pom.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<project
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+	xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>org.apache.hadoop</groupId>
+		<artifactId>gateway</artifactId>
+		<version>0.5.0-SNAPSHOT</version>
+	</parent>
+	<artifactId>gateway-provider-rewrite-step-encrypt-uri</artifactId>
+	<name>gateway-provider-rewrite-step-encrypt-uri</name>
+	<description>An extension of the gateway that supports securing request/response content.</description>
+
+	<licenses>
+		<license>
+			<name>The Apache Software License, Version 2.0</name>
+			<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+			<distribution>repo</distribution>
+		</license>
+	</licenses>
+
+	<dependencies>
+
+		<dependency>
+			<groupId>${gateway-group}</groupId>
+			<artifactId>gateway-util-common</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>${gateway-group}</groupId>
+			<artifactId>gateway-util-urltemplate</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>${gateway-group}</groupId>
+			<artifactId>gateway-i18n</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>${gateway-group}</groupId>
+			<artifactId>gateway-i18n-logging-log4j</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>${gateway-group}</groupId>
+			<artifactId>gateway-spi</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>${gateway-group}</groupId>
+			<artifactId>gateway-provider-rewrite</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>commons-codec</groupId>
+			<artifactId>commons-codec</artifactId>
+		</dependency>
+
+		<!-- ********** ********** ********** ********** ********** ********** -->
+		<!-- ********** Test Dependencies ********** -->
+		<!-- ********** ********** ********** ********** ********** ********** -->
+
+		<dependency>
+			<groupId>${gateway-group}</groupId>
+			<artifactId>gateway-test-utils</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>${gateway-group}</groupId>
+			<artifactId>gateway-server</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.hamcrest</groupId>
+			<artifactId>hamcrest-core</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.hamcrest</groupId>
+			<artifactId>hamcrest-library</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<!-- This must be after restassured otherwise is messes up the hamcrest
+			dependencies. -->
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.easymock</groupId>
+			<artifactId>easymock</artifactId>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/EncryptStepContextParams.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/EncryptStepContextParams.java b/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/EncryptStepContextParams.java
new file mode 100644
index 0000000..aa7ab49
--- /dev/null
+++ b/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/EncryptStepContextParams.java
@@ -0,0 +1,47 @@
+/**
+ * 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.gateway.encrypturi;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.hadoop.gateway.util.urltemplate.Params;
+
+public class EncryptStepContextParams implements Params {
+  Map<String, List<String>> params = new HashMap<String, List<String>>();
+
+  public EncryptStepContextParams() {
+  }
+
+  @Override
+  public List<String> resolve( String name ) {
+    return params.get( name );
+  }
+
+  @Override
+  public Set<String> getNames() {
+    return params.keySet();
+  }
+
+  public void addParam( String name, List<String> values ) {
+    params.put( name, values );
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/api/DecryptUriDescriptor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/api/DecryptUriDescriptor.java b/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/api/DecryptUriDescriptor.java
new file mode 100644
index 0000000..01dd38f
--- /dev/null
+++ b/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/api/DecryptUriDescriptor.java
@@ -0,0 +1,39 @@
+/**
+ * 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.gateway.encrypturi.api;
+
+import org.apache.hadoop.gateway.filter.rewrite.ext.UrlRewriteActionDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteActionDescriptorBase;
+
+public class DecryptUriDescriptor extends UrlRewriteActionDescriptorBase
+    implements UrlRewriteActionDescriptor {
+  public static final String STEP_NAME = "decrypt";
+  private String param;
+
+  public DecryptUriDescriptor() {
+    super( STEP_NAME );
+  }
+
+  public String getParam() {
+    return param;
+  }
+
+  public void setParam( String param ) {
+    this.param = param;
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/api/EncryptUriDescriptor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/api/EncryptUriDescriptor.java b/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/api/EncryptUriDescriptor.java
new file mode 100644
index 0000000..4584d24
--- /dev/null
+++ b/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/api/EncryptUriDescriptor.java
@@ -0,0 +1,49 @@
+/**
+ * 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.gateway.encrypturi.api;
+
+import org.apache.hadoop.gateway.filter.rewrite.ext.UrlRewriteActionDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteActionDescriptorBase;
+
+public class EncryptUriDescriptor extends UrlRewriteActionDescriptorBase
+    implements UrlRewriteActionDescriptor {
+  public static final String STEP_NAME = "encrypt";
+  public static final String PASSWORD_ALIAS = "encryptQueryString";
+  private String template;
+  private String param;
+
+  public EncryptUriDescriptor() {
+    super( STEP_NAME );
+  }
+
+  public String getTemplate() {
+    return template;
+  }
+
+  public void setTemplate( String template ) {
+    this.template = template;
+  }
+
+  public String getParam() {
+    return param;
+  }
+
+  public void setParam( String param ) {
+    this.param = param;
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/impl/DecryptUriProcessor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/impl/DecryptUriProcessor.java b/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/impl/DecryptUriProcessor.java
new file mode 100644
index 0000000..cbd26b7
--- /dev/null
+++ b/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/impl/DecryptUriProcessor.java
@@ -0,0 +1,89 @@
+/**
+ * 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.gateway.encrypturi.impl;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.hadoop.gateway.encrypturi.EncryptStepContextParams;
+import org.apache.hadoop.gateway.encrypturi.api.DecryptUriDescriptor;
+import org.apache.hadoop.gateway.encrypturi.api.EncryptUriDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteEnvironment;
+import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteContext;
+import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteStepProcessor;
+import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteStepStatus;
+import org.apache.hadoop.gateway.services.GatewayServices;
+import org.apache.hadoop.gateway.services.security.CryptoService;
+import org.apache.hadoop.gateway.services.security.EncryptionResult;
+import org.apache.hadoop.gateway.util.urltemplate.Expander;
+import org.apache.hadoop.gateway.util.urltemplate.Parser;
+import org.apache.hadoop.gateway.util.urltemplate.Template;
+
+public class DecryptUriProcessor
+    implements UrlRewriteStepProcessor<DecryptUriDescriptor> {
+
+  private String clusterName;
+  private CryptoService cryptoService;
+  private String param;
+
+  @Override
+  public String getType() {
+    return DecryptUriDescriptor.STEP_NAME;
+  }
+
+  @Override
+  public void initialize( UrlRewriteEnvironment environment, DecryptUriDescriptor descriptor ) throws Exception {
+    clusterName = environment.getAttribute( GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE );
+    GatewayServices services = environment.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+    cryptoService = (CryptoService) services.getService(GatewayServices.CRYPTO_SERVICE);
+    param = descriptor.getParam();
+  }
+
+  @Override
+  public UrlRewriteStepStatus process( UrlRewriteContext context ) throws Exception {
+    if( param != null && !param.isEmpty() ) {
+      Template template = Parser.parse( "{" + param + "}" );
+      String resolvedTemplate = Expander.expandToString( template, context.getParameters(), context.getEvaluator() );
+      String url = decode( resolvedTemplate );
+      EncryptStepContextParams params = new EncryptStepContextParams();
+      params.addParam( param, Arrays.asList( url ) );
+      context.addParameters( params );
+      return UrlRewriteStepStatus.SUCCESS;
+    }
+    return UrlRewriteStepStatus.FAILURE;
+  }
+
+  @Override
+  public void destroy() {
+  }
+
+  private String decode( String string ) throws UnsupportedEncodingException {
+    byte[] bytes = Base64.decodeBase64( string );
+    EncryptionResult result = EncryptionResult.fromByteArray(bytes);
+    byte[] clear = cryptoService.decryptForCluster(clusterName,
+        EncryptUriDescriptor.PASSWORD_ALIAS,
+        result.cipher,
+        result.iv,
+        result.salt);
+    if (clear != null) {
+      return new String(clear);
+    }
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptUriDeploymentContributor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptUriDeploymentContributor.java b/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptUriDeploymentContributor.java
new file mode 100644
index 0000000..fbe266a
--- /dev/null
+++ b/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptUriDeploymentContributor.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.gateway.encrypturi.impl;
+
+import org.apache.hadoop.gateway.deploy.DeploymentContext;
+import org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor;
+import org.apache.hadoop.gateway.deploy.ProviderDeploymentContributorBase;
+import org.apache.hadoop.gateway.descriptor.FilterParamDescriptor;
+import org.apache.hadoop.gateway.descriptor.ResourceDescriptor;
+import org.apache.hadoop.gateway.encrypturi.api.EncryptUriDescriptor;
+import org.apache.hadoop.gateway.services.security.AliasService;
+import org.apache.hadoop.gateway.topology.Provider;
+import org.apache.hadoop.gateway.topology.Service;
+
+import java.util.List;
+
+public class EncryptUriDeploymentContributor
+    extends ProviderDeploymentContributorBase
+    implements ProviderDeploymentContributor {
+
+  public static final String PROVIDER_ROLE_NAME = "encrypt";
+  public static final String PROVIDER_IMPL_NAME = "default";
+  private AliasService as;
+
+  @Override
+  public String getRole() {
+    return PROVIDER_ROLE_NAME;
+  }
+
+  @Override
+  public String getName() {
+    return PROVIDER_IMPL_NAME;
+  }
+
+  public void setAliasService(AliasService as) {
+    this.as = as;
+  }
+
+  @Override
+  public void initializeContribution(DeploymentContext context) {
+    super.initializeContribution(context);
+
+    String clusterName = context.getTopology().getName();
+
+    // we don't want to overwrite an existing alias from a previous topology deployment
+    // so we can't just blindly generateAlias here.
+    // this version of getPassword will generate a value for it only if missing
+    this.as.getPasswordFromAliasForCluster(clusterName, EncryptUriDescriptor.PASSWORD_ALIAS, true);
+  }
+
+  @Override
+  public void contributeProvider( DeploymentContext context, Provider provider ) {
+  }
+
+  @Override
+  public void contributeFilter(
+      DeploymentContext context,
+      Provider provider,
+      Service service,
+      ResourceDescriptor resource,
+      List<FilterParamDescriptor> params ) {
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptUriProcessor.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptUriProcessor.java b/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptUriProcessor.java
new file mode 100644
index 0000000..d9cfd13
--- /dev/null
+++ b/gateway-provider-rewrite-step-encrypt-uri/src/main/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptUriProcessor.java
@@ -0,0 +1,85 @@
+/**
+ * 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.gateway.encrypturi.impl;
+
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.hadoop.gateway.encrypturi.EncryptStepContextParams;
+import org.apache.hadoop.gateway.encrypturi.api.EncryptUriDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteEnvironment;
+import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteContext;
+import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteStepProcessor;
+import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteStepStatus;
+import org.apache.hadoop.gateway.services.GatewayServices;
+import org.apache.hadoop.gateway.services.security.CryptoService;
+import org.apache.hadoop.gateway.services.security.EncryptionResult;
+import org.apache.hadoop.gateway.util.urltemplate.Expander;
+import org.apache.hadoop.gateway.util.urltemplate.Parser;
+import org.apache.hadoop.gateway.util.urltemplate.Template;
+
+public class EncryptUriProcessor
+    implements UrlRewriteStepProcessor<EncryptUriDescriptor> {
+
+  private String clusterName;
+  private CryptoService cryptoService;
+  private String template;
+  private String param;
+
+  @Override
+  public String getType() {
+    return EncryptUriDescriptor.STEP_NAME;
+  }
+
+  @Override
+  public void initialize( UrlRewriteEnvironment environment, EncryptUriDescriptor descriptor ) throws Exception {
+    clusterName = environment.getAttribute( GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE );
+    GatewayServices services = environment.getAttribute(GatewayServices.GATEWAY_SERVICES_ATTRIBUTE);
+    cryptoService = (CryptoService) services.getService(GatewayServices.CRYPTO_SERVICE);
+    template = descriptor.getTemplate();
+    param = descriptor.getParam();
+  }
+
+  @Override
+  public UrlRewriteStepStatus process( UrlRewriteContext context ) throws Exception {
+    if( param != null && !param.isEmpty() && template != null && !template.isEmpty() ) {
+      Template uri = Parser.parse( template );
+      String resolvedTemplate = Expander.expandToString( uri, context.getParameters(), context.getEvaluator() );
+      if( resolvedTemplate != null && !resolvedTemplate.isEmpty() ) {
+        String endcoedUrl = encode( resolvedTemplate );
+        EncryptStepContextParams params = new EncryptStepContextParams();
+        params.addParam( param, Arrays.asList( endcoedUrl ) );
+        context.addParameters( params );
+        return UrlRewriteStepStatus.SUCCESS;
+      }
+    }
+    return UrlRewriteStepStatus.FAILURE;
+  }
+
+  @Override
+  public void destroy() {
+  }
+
+  private String encode( String string ) throws UnsupportedEncodingException {
+    EncryptionResult result = cryptoService.encryptForCluster(clusterName, EncryptUriDescriptor.PASSWORD_ALIAS, string.getBytes("UTF-8"));
+    string = Base64.encodeBase64URLSafeString(result.toByteAray());
+    return string;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite-step-encrypt-uri/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-encrypt-uri/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor b/gateway-provider-rewrite-step-encrypt-uri/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
new file mode 100644
index 0000000..328b0a0
--- /dev/null
+++ b/gateway-provider-rewrite-step-encrypt-uri/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor
@@ -0,0 +1,19 @@
+##########################################################################
+# 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.
+##########################################################################
+
+org.apache.hadoop.gateway.encrypturi.impl.EncryptUriDeploymentContributor

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite-step-encrypt-uri/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteStepDescriptor
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-encrypt-uri/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteStepDescriptor b/gateway-provider-rewrite-step-encrypt-uri/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteStepDescriptor
new file mode 100644
index 0000000..1404210
--- /dev/null
+++ b/gateway-provider-rewrite-step-encrypt-uri/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteStepDescriptor
@@ -0,0 +1,20 @@
+##########################################################################
+# 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.
+##########################################################################
+
+org.apache.hadoop.gateway.encrypturi.api.EncryptUriDescriptor
+org.apache.hadoop.gateway.encrypturi.api.DecryptUriDescriptor

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite-step-encrypt-uri/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteStepProcessor
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-encrypt-uri/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteStepProcessor b/gateway-provider-rewrite-step-encrypt-uri/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteStepProcessor
new file mode 100644
index 0000000..14bd1d5
--- /dev/null
+++ b/gateway-provider-rewrite-step-encrypt-uri/src/main/resources/META-INF/services/org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteStepProcessor
@@ -0,0 +1,20 @@
+##########################################################################
+# 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.
+##########################################################################
+
+org.apache.hadoop.gateway.encrypturi.impl.EncryptUriProcessor
+org.apache.hadoop.gateway.encrypturi.impl.DecryptUriProcessor

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/api/DecryptUriDescriptorTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/api/DecryptUriDescriptorTest.java b/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/api/DecryptUriDescriptorTest.java
new file mode 100644
index 0000000..c51bbd7
--- /dev/null
+++ b/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/api/DecryptUriDescriptorTest.java
@@ -0,0 +1,55 @@
+/**
+ * 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.gateway.encrypturi.api;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteStepDescriptor;
+import org.junit.Test;
+
+public class DecryptUriDescriptorTest {
+
+  @Test
+  @SuppressWarnings("rawtypes")
+  public void testServiceLoader() throws Exception {
+    ServiceLoader loader = ServiceLoader.load( UrlRewriteStepDescriptor.class );
+    Iterator iterator = loader.iterator();
+    assertThat( "Service iterator empty.", iterator.hasNext() );
+    while( iterator.hasNext() ) {
+      Object object = iterator.next();
+      if( object instanceof DecryptUriDescriptor ) {
+        return;
+      }
+    }
+    fail( "Failed to find " + DecryptUriDescriptor.class.getName() + " via service loader." );
+  }
+
+  @Test
+  public void testGetAndSet() {
+    DecryptUriDescriptor descriptor = new DecryptUriDescriptor();
+    assertThat( descriptor.type(), is( "decrypt" ) );
+    assertThat( descriptor.getParam(), nullValue() );
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/api/EncryptUriDescriptorTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/api/EncryptUriDescriptorTest.java b/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/api/EncryptUriDescriptorTest.java
new file mode 100644
index 0000000..ea0c61a
--- /dev/null
+++ b/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/api/EncryptUriDescriptorTest.java
@@ -0,0 +1,55 @@
+/**
+ * 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.gateway.encrypturi.api;
+
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteStepDescriptor;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.fail;
+
+public class EncryptUriDescriptorTest {
+
+  @Test
+  @SuppressWarnings("rawtypes")
+  public void testServiceLoader() throws Exception {
+    ServiceLoader loader = ServiceLoader.load( UrlRewriteStepDescriptor.class );
+    Iterator iterator = loader.iterator();
+    assertThat( "Service iterator empty.", iterator.hasNext() );
+    while( iterator.hasNext() ) {
+      Object object = iterator.next();
+      if( object instanceof EncryptUriDescriptor ) {
+        return;
+      }
+    }
+    fail( "Failed to find " + EncryptUriDescriptor.class.getName() + " via service loader." );
+  }
+
+  @Test
+  public void testGetAndSet() {
+    EncryptUriDescriptor descriptor = new EncryptUriDescriptor();
+    assertThat( descriptor.type(), is( "encrypt" ) );
+    assertThat( descriptor.getParam(), nullValue() );
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptDecryptUriProcessorTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptDecryptUriProcessorTest.java b/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptDecryptUriProcessorTest.java
new file mode 100644
index 0000000..9e9f93c
--- /dev/null
+++ b/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptDecryptUriProcessorTest.java
@@ -0,0 +1,157 @@
+/**
+ * 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.gateway.encrypturi.impl;
+
+import org.apache.hadoop.gateway.encrypturi.EncryptStepContextParams;
+import org.apache.hadoop.gateway.encrypturi.api.DecryptUriDescriptor;
+import org.apache.hadoop.gateway.encrypturi.api.EncryptUriDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteEnvironment;
+import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteContext;
+import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteStepProcessor;
+import org.apache.hadoop.gateway.filter.rewrite.spi.UrlRewriteStepStatus;
+import org.apache.hadoop.gateway.services.GatewayServices;
+import org.apache.hadoop.gateway.services.security.AliasService;
+import org.apache.hadoop.gateway.services.security.CryptoService;
+import org.apache.hadoop.gateway.services.security.impl.DefaultCryptoService;
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.text.IsEmptyString.isEmptyOrNullString;
+import static org.junit.Assert.fail;
+
+
+public class EncryptDecryptUriProcessorTest {
+
+  @SuppressWarnings("rawtypes")
+  @Test
+  public void testServiceLoader() throws Exception {
+    ServiceLoader loader = ServiceLoader.load( UrlRewriteStepProcessor.class );
+    Iterator iterator = loader.iterator();
+    assertThat( "Service iterator empty.", iterator.hasNext() );
+    while( iterator.hasNext() ) {
+      Object object = iterator.next();
+      if( object instanceof EncryptUriProcessor ) {
+        return;
+      }
+    }
+    fail( "Failed to find " + EncryptUriProcessor.class.getName() + " via service loader." );
+
+    loader = ServiceLoader.load( UrlRewriteStepProcessor.class );
+    iterator = loader.iterator();
+    assertThat( "Service iterator empty.", iterator.hasNext() );
+    while( iterator.hasNext() ) {
+      Object object = iterator.next();
+      if( object instanceof DecryptUriProcessor ) {
+        return;
+      }
+    }
+    fail( "Failed to find " + DecryptUriProcessor.class.getName() + " via service loader." );
+  }
+
+  @Test
+  public void testEncryptDecrypt() throws Exception {
+    String encryptedValueParamName = "address";
+    String clusterName = "test-cluster-name";
+    String passwordAlias = "encryptQueryString";
+
+    // Test encryption.  Result is in encryptedAdrress
+
+    AliasService as = EasyMock.createNiceMock( AliasService.class );
+    String secret = "asdf";
+    EasyMock.expect( as.getPasswordFromAliasForCluster( clusterName, passwordAlias ) ).andReturn( secret.toCharArray() ).anyTimes();
+    CryptoService cryptoService = new DefaultCryptoService();
+    ((DefaultCryptoService)cryptoService).setAliasService( as );
+    GatewayServices gatewayServices = EasyMock.createNiceMock( GatewayServices.class );
+    EasyMock.expect( gatewayServices.getService( GatewayServices.CRYPTO_SERVICE ) ).andReturn( cryptoService );
+
+    UrlRewriteEnvironment encEnvironment = EasyMock.createNiceMock( UrlRewriteEnvironment.class );
+    EasyMock.expect( encEnvironment.getAttribute( GatewayServices.GATEWAY_SERVICES_ATTRIBUTE ) ).andReturn( gatewayServices ).anyTimes();
+    EasyMock.expect( encEnvironment.getAttribute( GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE ) ).andReturn( clusterName ).anyTimes();
+    UrlRewriteContext encContext = EasyMock.createNiceMock( UrlRewriteContext.class );
+
+    EncryptStepContextParams hostPortParams = new EncryptStepContextParams();
+    hostPortParams.addParam( "host", Arrays.asList( "host.yarn.com" ) );
+    hostPortParams.addParam( "port", Arrays.asList( "8088" ) );
+    EasyMock.expect( encContext.getParameters() ).andReturn( hostPortParams );
+
+
+    Capture<EncryptStepContextParams> encodedValue = new Capture<EncryptStepContextParams>();
+    encContext.addParameters( EasyMock.capture( encodedValue ) );
+
+    EasyMock.replay( gatewayServices, as, encEnvironment, encContext );
+
+    EncryptUriDescriptor descriptor = new EncryptUriDescriptor();
+    descriptor.setTemplate( "{host}:{port}" );
+    descriptor.setParam( encryptedValueParamName );
+    EncryptUriProcessor processor = new EncryptUriProcessor();
+    processor.initialize( encEnvironment, descriptor );
+    UrlRewriteStepStatus encStatus = processor.process( encContext );
+
+    assertThat( encStatus, is ( UrlRewriteStepStatus.SUCCESS ) );
+    assertThat( encodedValue.getValue(), notNullValue() );
+    assertThat( encodedValue.getValue().resolve( encryptedValueParamName ).size(), is( 1 ) );
+    String encryptedAdrress = encodedValue.getValue().resolve( encryptedValueParamName ).get( 0 );
+    assertThat( encryptedAdrress, not( isEmptyOrNullString() ) );
+    assertThat( encryptedAdrress, not( "{host}:{port}" ) );
+    assertThat( encryptedAdrress, not( "hdp:8088" ) );
+
+    // Test decryption.  Result is in dectryptedAdrress.
+    String decParam = "foo";
+    gatewayServices = EasyMock.createNiceMock( GatewayServices.class );
+    EasyMock.expect( gatewayServices.getService( GatewayServices.CRYPTO_SERVICE ) ).andReturn( cryptoService );
+    as = EasyMock.createNiceMock( AliasService.class );
+    EasyMock.expect( as.getPasswordFromAliasForCluster( clusterName, passwordAlias ) ).andReturn( secret.toCharArray() ).anyTimes();
+
+    UrlRewriteEnvironment decEnvironment = EasyMock.createNiceMock( UrlRewriteEnvironment.class );
+    EasyMock.expect( decEnvironment.getAttribute( GatewayServices.GATEWAY_SERVICES_ATTRIBUTE ) ).andReturn( gatewayServices ).anyTimes();
+    EasyMock.expect( decEnvironment.getAttribute( GatewayServices.GATEWAY_CLUSTER_ATTRIBUTE ) ).andReturn( clusterName ).anyTimes();
+    UrlRewriteContext decContext = EasyMock.createNiceMock( UrlRewriteContext.class );
+
+    EncryptStepContextParams encryptedParams = new EncryptStepContextParams();
+    encryptedParams.addParam( decParam, Arrays.asList( encryptedAdrress ) ); //Value was encrypted by EncryptUriProcessor
+    encryptedParams.addParam( "foo1", Arrays.asList( "test" ) );
+    EasyMock.expect( decContext.getParameters() ).andReturn( encryptedParams );
+
+    Capture<EncryptStepContextParams> decodedValue = new Capture<EncryptStepContextParams>();
+    decContext.addParameters( EasyMock.capture( decodedValue ) );
+
+    EasyMock.replay( gatewayServices, as, decEnvironment, decContext );
+
+    DecryptUriDescriptor decDescriptor = new DecryptUriDescriptor();
+    decDescriptor.setParam( decParam );
+
+    DecryptUriProcessor decProcessor = new DecryptUriProcessor();
+    decProcessor.initialize( decEnvironment, decDescriptor );
+    UrlRewriteStepStatus decStatus = decProcessor.process( decContext );
+    assertThat( decStatus, is ( UrlRewriteStepStatus.SUCCESS ) );
+    assertThat( decodedValue.getValue(), notNullValue() );
+    assertThat( decodedValue.getValue().resolve( decParam ).size(), is( 1 ) );
+    String dectryptedAdrress = decodedValue.getValue().resolve( decParam ).get( 0 );
+    assertThat( dectryptedAdrress, is ( "host.yarn.com:8088" ) );
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptUriDeploymentContributorTest.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptUriDeploymentContributorTest.java b/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptUriDeploymentContributorTest.java
new file mode 100644
index 0000000..7f09224
--- /dev/null
+++ b/gateway-provider-rewrite-step-encrypt-uri/src/test/java/org/apache/hadoop/gateway/encrypturi/impl/EncryptUriDeploymentContributorTest.java
@@ -0,0 +1,105 @@
+/**
+ * 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.gateway.encrypturi.impl;
+
+import org.apache.hadoop.gateway.deploy.DeploymentContext;
+import org.apache.hadoop.gateway.deploy.ProviderDeploymentContributor;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteEnvironment;
+import org.apache.hadoop.gateway.services.GatewayServices;
+import org.apache.hadoop.gateway.services.security.AliasService;
+import org.apache.hadoop.gateway.services.security.CryptoService;
+import org.apache.hadoop.gateway.services.security.impl.DefaultCryptoService;
+import org.apache.hadoop.gateway.topology.Provider;
+import org.apache.hadoop.gateway.topology.Topology;
+import org.easymock.EasyMock;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.fail;
+
+public class EncryptUriDeploymentContributorTest {
+
+  @SuppressWarnings("rawtypes")
+  @Test
+  public void testServiceLoader() throws Exception {
+    ServiceLoader loader = ServiceLoader.load( ProviderDeploymentContributor.class );
+    Iterator iterator = loader.iterator();
+    assertThat( "Service iterator empty.", iterator.hasNext() );
+    while( iterator.hasNext() ) {
+      Object object = iterator.next();
+      if( object instanceof EncryptUriDeploymentContributor ) {
+        return;
+      }
+    }
+    fail( "Failed to find " + EncryptUriDeploymentContributor.class.getName() + " via service loader." );
+  }
+
+  @Test
+  public void testDeployment() throws IOException {
+    WebArchive webArchive = ShrinkWrap.create( WebArchive.class, "test-acrhive" );
+
+    Provider provider = new Provider();
+    provider.setEnabled( true );
+    provider.setName( EncryptUriDeploymentContributor.PROVIDER_ROLE_NAME );
+
+    Topology topology = new Topology();
+    topology.setName( "Sample" );
+
+    DeploymentContext context = EasyMock.createNiceMock( DeploymentContext.class );
+
+    EasyMock.expect( context.getWebArchive() ).andReturn( webArchive ).anyTimes();
+    EasyMock.expect( context.getTopology() ).andReturn( topology ).anyTimes();
+    EasyMock.replay( context );
+
+    AliasService as = EasyMock.createNiceMock( AliasService.class );
+    CryptoService cryptoService = new DefaultCryptoService();
+    ((DefaultCryptoService) cryptoService).setAliasService( as );
+
+    GatewayServices gatewayServices = EasyMock.createNiceMock( GatewayServices.class );
+    EasyMock.expect( gatewayServices.getService( GatewayServices.CRYPTO_SERVICE ) ).andReturn( cryptoService ).anyTimes();
+
+    UrlRewriteEnvironment encEnvironment = EasyMock.createNiceMock( UrlRewriteEnvironment.class );
+    EasyMock.expect( encEnvironment.getAttribute( GatewayServices.GATEWAY_SERVICES_ATTRIBUTE ) ).andReturn( gatewayServices ).anyTimes();
+
+    EncryptUriDeploymentContributor contributor = new EncryptUriDeploymentContributor();
+    contributor.setAliasService( as );
+
+    assertThat( contributor.getRole(), is( EncryptUriDeploymentContributor.PROVIDER_ROLE_NAME ) );
+    assertThat( contributor.getName(), is( EncryptUriDeploymentContributor.PROVIDER_IMPL_NAME ) );
+
+    // Just make sure it doesn't blow up.
+    contributor.contributeFilter( null, null, null, null, null );
+
+    // Just make sure it doesn't blow up.
+    contributor.initializeContribution( context );
+
+    contributor.contributeProvider( context, provider );
+
+    // Just make sure it doesn't blow up.
+    contributor.finalizeContribution( context );
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/ext/UrlRewriteActionRewriteProcessorExt.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/ext/UrlRewriteActionRewriteProcessorExt.java b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/ext/UrlRewriteActionRewriteProcessorExt.java
index d0785a6..61dd609 100644
--- a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/ext/UrlRewriteActionRewriteProcessorExt.java
+++ b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/ext/UrlRewriteActionRewriteProcessorExt.java
@@ -39,7 +39,11 @@ public class UrlRewriteActionRewriteProcessorExt
   @Override
   public void initialize( UrlRewriteEnvironment environment, UrlRewriteActionRewriteDescriptorExt descriptor ) throws Exception {
     this.expander = new Expander();
-    this.template = Parser.parse( descriptor.parameter() );
+    if ( descriptor.parameter() != null ) {
+      this.template = Parser.parse( descriptor.parameter() );
+    } else {
+      this.template = Parser.parse( "" );
+    }
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/spi/UrlRewriteContext.java
----------------------------------------------------------------------
diff --git a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/spi/UrlRewriteContext.java b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/spi/UrlRewriteContext.java
index 5fe99a4..092a6b0 100644
--- a/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/spi/UrlRewriteContext.java
+++ b/gateway-provider-rewrite/src/main/java/org/apache/hadoop/gateway/filter/rewrite/spi/UrlRewriteContext.java
@@ -32,6 +32,10 @@ public interface UrlRewriteContext {
 
   void setCurrentUrl( Template url );
 
+  /**
+   * Adds parameters to the rewrite context and replaces some of them if they already exist
+   * @param parameters the parameters to be added or replaced
+   */
   void addParameters( Params parameters );
 
   Params getParameters();

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-release/home/conf/topologies/sandbox.xml
----------------------------------------------------------------------
diff --git a/gateway-release/home/conf/topologies/sandbox.xml b/gateway-release/home/conf/topologies/sandbox.xml
index fc259b1..155dc7d 100644
--- a/gateway-release/home/conf/topologies/sandbox.xml
+++ b/gateway-release/home/conf/topologies/sandbox.xml
@@ -120,4 +120,9 @@
         <url>http://localhost:10001/cliservice</url>
     </service>
 
+    <service>
+        <role>RESOURCEMANAGER</role>
+        <url>http://localhost:8088/ws</url>
+    </service>
+
 </topology>

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-release/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-release/pom.xml b/gateway-release/pom.xml
index 84834ef..a449497 100644
--- a/gateway-release/pom.xml
+++ b/gateway-release/pom.xml
@@ -147,6 +147,10 @@
         </dependency>
         <dependency>
             <groupId>${gateway-group}</groupId>
+            <artifactId>gateway-service-yarn-rm</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${gateway-group}</groupId>
             <artifactId>gateway-provider-rewrite</artifactId>
         </dependency>
         <dependency>
@@ -155,6 +159,10 @@
         </dependency>
         <dependency>
             <groupId>${gateway-group}</groupId>
+            <artifactId>gateway-provider-rewrite-step-encrypt-uri</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${gateway-group}</groupId>
             <artifactId>gateway-provider-rewrite-func-hostmap-static</artifactId>
         </dependency>
         <dependency>

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-service-yarn-rm/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-service-yarn-rm/pom.xml b/gateway-service-yarn-rm/pom.xml
new file mode 100644
index 0000000..f8a9c25
--- /dev/null
+++ b/gateway-service-yarn-rm/pom.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.hadoop</groupId>
+    <artifactId>gateway</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>gateway-service-yarn-rm</artifactId>
+  <name>gateway-service-yarn-rm</name>
+  <description>The extension to the gateway for supporting YARN Resource Manager REST API.</description>
+
+    <licenses>
+        <license>
+            <name>The Apache Software License, Version 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+        </license>
+    </licenses>
+
+    <dependencies>
+        <dependency>
+            <groupId>${gateway-group}</groupId>
+            <artifactId>gateway-spi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${gateway-group}</groupId>
+            <artifactId>gateway-provider-rewrite</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>${gateway-group}</groupId>
+            <artifactId>gateway-test-utils</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-service-yarn-rm/src/main/java/org/apache/hadoop/gateway/yarn/rm/ResourceManagerDeploymentContributor.java
----------------------------------------------------------------------
diff --git a/gateway-service-yarn-rm/src/main/java/org/apache/hadoop/gateway/yarn/rm/ResourceManagerDeploymentContributor.java b/gateway-service-yarn-rm/src/main/java/org/apache/hadoop/gateway/yarn/rm/ResourceManagerDeploymentContributor.java
new file mode 100644
index 0000000..21e1b2e
--- /dev/null
+++ b/gateway-service-yarn-rm/src/main/java/org/apache/hadoop/gateway/yarn/rm/ResourceManagerDeploymentContributor.java
@@ -0,0 +1,150 @@
+/**
+ * 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.gateway.yarn.rm;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.hadoop.gateway.deploy.DeploymentContext;
+import org.apache.hadoop.gateway.deploy.ServiceDeploymentContributorBase;
+import org.apache.hadoop.gateway.descriptor.FilterParamDescriptor;
+import org.apache.hadoop.gateway.descriptor.ResourceDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteRulesDescriptor;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteRulesDescriptorFactory;
+import org.apache.hadoop.gateway.filter.rewrite.api.UrlRewriteServletFilter;
+import org.apache.hadoop.gateway.topology.Service;
+
+public class ResourceManagerDeploymentContributor extends
+    ServiceDeploymentContributorBase {
+  private static final String RULES_RESOURCE = ResourceManagerDeploymentContributor.class
+      .getName().replace( '.', '/' ) + "/rewrite.xml";
+  private static final String EXTERNAL_PATH = "/resourcemanager";
+  private static final String PROXY_PATH = "/resourcemanager/proxy";
+
+  @Override
+  public String getRole() {
+    return "RESOURCEMANAGER";
+  }
+
+  @Override
+  public String getName() {
+    return "resourcemanager";
+  }
+
+  @Override
+  public void contributeService(DeploymentContext context, Service service)
+      throws Exception {
+    contributeRewriteRules( context, service );
+    contributeResources( context, service );
+  }
+
+  private void contributeRewriteRules(DeploymentContext context, Service service)
+      throws URISyntaxException, IOException {
+    UrlRewriteRulesDescriptor serviceRules = loadRulesFromClassPath();
+    UrlRewriteRulesDescriptor clusterRules = context.getDescriptor( "rewrite" );
+    clusterRules.addRules( serviceRules );
+  }
+
+  private UrlRewriteRulesDescriptor loadRulesFromClassPath() throws IOException {
+    InputStream stream = this.getClass().getClassLoader()
+        .getResourceAsStream( RULES_RESOURCE );
+    Reader reader = new InputStreamReader( stream );
+    UrlRewriteRulesDescriptor rules = UrlRewriteRulesDescriptorFactory.load(
+        "xml", reader );
+    reader.close();
+    stream.close();
+    return rules;
+  }
+
+  private void contributeResources(DeploymentContext context, Service service)
+      throws URISyntaxException {
+    Map<String, String> filterParams = new HashMap<String, String>();
+
+    contributeResource( context, service, EXTERNAL_PATH + "/v1/cluster/", null );
+
+    contributeResource( context, service, EXTERNAL_PATH + "/v1/cluster/**?**", null );
+
+    filterParams.clear();
+    filterParams.put( UrlRewriteServletFilter.RESPONSE_BODY_FILTER_PARAM, getQualifiedName() + "/apps/outbound" );
+    contributeResource( context, service, EXTERNAL_PATH + "/v1/cluster/apps?**", filterParams );
+
+    filterParams.clear();
+    filterParams.put( UrlRewriteServletFilter.RESPONSE_BODY_FILTER_PARAM, getQualifiedName() + "/app/outbound" );
+    contributeResource( context, service, EXTERNAL_PATH + "/v1/cluster/apps/*?**", filterParams );
+
+    filterParams.clear();
+    filterParams.put( UrlRewriteServletFilter.RESPONSE_BODY_FILTER_PARAM, getQualifiedName() + "/appattempts/outbound" );
+    contributeResource( context, service, EXTERNAL_PATH + "/v1/cluster/apps/*/appattempts?**", filterParams );
+
+    filterParams.clear();
+    filterParams.put( UrlRewriteServletFilter.RESPONSE_BODY_FILTER_PARAM, getQualifiedName() + "/nodes/outbound" );
+    contributeResource( context, service, EXTERNAL_PATH + "/v1/cluster/nodes?**", filterParams );
+
+    filterParams.clear();
+    filterParams.put( UrlRewriteServletFilter.REQUEST_URL_RULE_PARAM, getQualifiedName() + "/nodeId/inbound" );
+    filterParams.put( UrlRewriteServletFilter.RESPONSE_BODY_FILTER_PARAM, getQualifiedName() + "/node/outbound" );
+    contributeResource( context, service, EXTERNAL_PATH + "/v1/cluster/nodes/*?**", filterParams );
+
+    filterParams.clear();
+    filterParams.put( UrlRewriteServletFilter.REQUEST_URL_RULE_PARAM, getQualifiedName() + "/inbound/proxy" );
+    contributeResource( context, service, PROXY_PATH + "/*/ws/v1/**?**", filterParams );
+
+    filterParams.clear();
+    filterParams.put( UrlRewriteServletFilter.RESPONSE_BODY_FILTER_PARAM, getQualifiedName() + "/proxy/jobattempts/outbound" );
+    contributeResource( context, service, PROXY_PATH + "/*/ws/v1/mapreduce/jobs/*/jobattempts", filterParams );
+
+
+    filterParams.clear();
+    filterParams.put( UrlRewriteServletFilter.RESPONSE_BODY_FILTER_PARAM, getQualifiedName() + "/proxy/taskattempts/outbound" );
+    contributeResource( context, service, PROXY_PATH + "/*/ws/v1/mapreduce/jobs/*/tasks/*/attempts", filterParams );
+
+    filterParams.clear();
+    filterParams.put( UrlRewriteServletFilter.RESPONSE_BODY_FILTER_PARAM, getQualifiedName() + "/proxy/taskattempt/outbound" );
+    contributeResource( context, service, PROXY_PATH + "/*/ws/v1/mapreduce/jobs/*/tasks/*/attempts/*", filterParams );
+  }
+
+  private void contributeResource( DeploymentContext context, Service service, String pattern, Map<String, String> filterParams ) throws URISyntaxException {
+    List<FilterParamDescriptor> params = new ArrayList<FilterParamDescriptor>();
+    ResourceDescriptor resource = context.getGatewayDescriptor().addResource();
+    resource.role( service.getRole() );
+    resource.pattern( pattern );
+    addWebAppSecFilters( context, service, resource );
+    addAuthenticationFilter( context, service, resource );
+    addIdentityAssertionFilter( context, service, resource );
+    addAuthorizationFilter( context, service, resource );
+    if ( filterParams != null ) {
+      for( Entry<String, String> filterParam : filterParams.entrySet() ) {
+        params.add( resource.createFilterParam().name( filterParam.getKey() ).value( filterParam.getValue() ) );
+      }
+    }
+    addRewriteFilter( context, service, resource, params );
+    addDispatchFilter( context, service, resource, "dispatch", "http-client" );
+  }
+
+  private String getQualifiedName() {
+    return getRole() + "/" + getName();
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-service-yarn-rm/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor
----------------------------------------------------------------------
diff --git a/gateway-service-yarn-rm/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor b/gateway-service-yarn-rm/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor
new file mode 100644
index 0000000..3db76c7
--- /dev/null
+++ b/gateway-service-yarn-rm/src/main/resources/META-INF/services/org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor
@@ -0,0 +1,19 @@
+##########################################################################
+# 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.
+##########################################################################
+
+org.apache.hadoop.gateway.yarn.rm.ResourceManagerDeploymentContributor
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-service-yarn-rm/src/main/resources/org/apache/hadoop/gateway/yarn/rm/ResourceManagerDeploymentContributor/rewrite.xml
----------------------------------------------------------------------
diff --git a/gateway-service-yarn-rm/src/main/resources/org/apache/hadoop/gateway/yarn/rm/ResourceManagerDeploymentContributor/rewrite.xml b/gateway-service-yarn-rm/src/main/resources/org/apache/hadoop/gateway/yarn/rm/ResourceManagerDeploymentContributor/rewrite.xml
new file mode 100644
index 0000000..b82f106
--- /dev/null
+++ b/gateway-service-yarn-rm/src/main/resources/org/apache/hadoop/gateway/yarn/rm/ResourceManagerDeploymentContributor/rewrite.xml
@@ -0,0 +1,193 @@
+<?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.
+-->
+<rules>
+
+    <rule dir="IN" name="RESOURCEMANAGER/resourcemanager/inbound/root" pattern="*://*:*/**/resourcemanager/v1/?{**}">
+        <rewrite template="{$serviceUrl[RESOURCEMANAGER]}/v1/?{**}"/>
+    </rule>
+
+    <rule dir="IN" name="RESOURCEMANAGER/resourcemanager/inbound/path" pattern="*://*:*/**/resourcemanager/v1/{path=**}?{**}">
+        <rewrite template="{$serviceUrl[RESOURCEMANAGER]}/v1/{path=**}/?{**}"/>
+    </rule>
+
+    <rule dir="IN" name="RESOURCEMANAGER/resourcemanager/inbound/proxy" pattern="*://*:*/**/resourcemanager/proxy/{appid=*}/ws/v1/{path=**}?{**}">
+        <decrypt-query/>
+        <match pattern="*://*:*/**/resourcemanager/proxy/{appid=*}/ws/v1/{path=**}?{scheme}?{host}?{port}?{**}"/>
+        <rewrite template="{scheme}://{host}:{port}/proxy/{appid=*}/ws/v1/{path=**}?{**}"/>
+    </rule>
+
+    <rule dir="OUT" name="RESOURCEMANAGER/resourcemanager/url/outbound">
+        <match pattern="*://*:*/**?**"/>
+		<rewrite template=""/>
+    </rule>
+    <rule dir="OUT" name="RESOURCEMANAGER/resourcemanager/trackingUrlHistory/outbound">
+        <match pattern="{scheme}://{host}:{port}/proxy/{appid=*}/jobhistory/job/**"/>
+		<rewrite template=""/>
+    </rule>
+    <rule dir="OUT" name="RESOURCEMANAGER/resourcemanager/trackingUrlAM/outbound">
+        <match pattern="{scheme}://{host}:{port}/proxy/{appid=*}"/>
+		<rewrite template="{gateway.url}/resourcemanager/proxy/{appid=*}?{scheme}?host={$hostmap(host)}?{port}?{**}"/>
+		<encrypt-query/>
+    </rule>
+    <rule dir="OUT" name="RESOURCEMANAGER/resourcemanager/hostport/outbound">
+        <match pattern="*:*"/>
+		<rewrite template=""/>
+    </rule>
+    <rule dir="OUT" name="RESOURCEMANAGER/resourcemanager/logsLink/outbound">
+        <match pattern="//*:*/**?**"/>
+		<rewrite template=""/>
+    </rule>
+    <rule dir="OUT" name="RESOURCEMANAGER/resourcemanager/host/outbound">
+		<rewrite template=""/>
+    </rule>
+    <rule dir="OUT" name="RESOURCEMANAGER/resourcemanager/nodeId/outbound">
+        <match pattern="{host=*}:{port=*}"/>
+        <encrypt template="{host}:{port}" param="encaddr"/>
+        <rewrite template="{encaddr}"/>
+    </rule>
+    <rule dir="IN" name="RESOURCEMANAGER/resourcemanager/nodeId/inbound">
+        <match pattern="*://*:*/**/resourcemanager/v1/cluster/nodes/{addr=*}?{**}"/>
+        <decrypt param="addr"/>
+        <rewrite template="{$serviceUrl[RESOURCEMANAGER]}/v1/cluster/nodes/{addr}?{**}"/>
+    </rule>
+
+    <filter name="RESOURCEMANAGER/resourcemanager/apps/outbound">
+        <content type="*/json">
+        	<buffer path="$.apps.app[*]">
+        		<detect path="$.trackingUI" value="History">
+					<apply path="$.trackingUrl" rule="RESOURCEMANAGER/resourcemanager/trackingUrlHistory/outbound"/>
+				</detect>
+				<detect path="$.trackingUI" value="ApplicationMaster">
+					<apply path="$.trackingUrl" rule="RESOURCEMANAGER/resourcemanager/trackingUrlAM/outbound"/>
+				</detect>
+				<apply path="$.amContainerLogs" rule="RESOURCEMANAGER/resourcemanager/url/outbound"/>
+            	<apply path="$.amHostHttpAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+        	</buffer>
+        </content>
+        <content type="*/xml">
+        	<buffer path="/apps/app">
+        		<detect path="trackingUI" value="History">
+					<apply path="trackingUrl" rule="RESOURCEMANAGER/resourcemanager/trackingUrlHistory/outbound"/>
+				</detect>
+				<detect path="trackingUI" value="ApplicationMaster">
+					<apply path="trackingUrl" rule="RESOURCEMANAGER/resourcemanager/trackingUrlAM/outbound"/>
+				</detect>
+				<apply path="amContainerLogs" rule="RESOURCEMANAGER/resourcemanager/url/outbound"/>
+            	<apply path="amHostHttpAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+        	</buffer>
+        </content>
+    </filter>
+
+    <filter name="RESOURCEMANAGER/resourcemanager/app/outbound">
+        <content type="*/json">
+        	<buffer path="$.app">
+	       		<detect path="$.trackingUI" value="History">
+	       			<apply path="$.trackingUrl" rule="RESOURCEMANAGER/resourcemanager/trackingUrlHistory/outbound"/>
+	       		</detect>
+	       		<detect path="$.trackingUI" value="ApplicationMaster">
+	       			<apply path="$.trackingUrl" rule="RESOURCEMANAGER/resourcemanager/trackingUrlAM/outbound"/>
+	       		</detect>
+	            <apply path="$.amContainerLogs" rule="RESOURCEMANAGER/resourcemanager/url/outbound"/>
+	            <apply path="$.amHostHttpAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+            </buffer>
+        </content>
+        <content type="*/xml">
+        	<buffer path="/app">
+	       		<detect path="trackingUI" value="History">
+	       			<apply path="trackingUrl" rule="RESOURCEMANAGER/resourcemanager/trackingUrlHistory/outbound"/>
+	       		</detect>
+	       		<detect path="trackingUI" value="ApplicationMaster">
+	       			<apply path="trackingUrl" rule="RESOURCEMANAGER/resourcemanager/trackingUrlAM/outbound"/>
+	       		</detect>
+	            <apply path="amContainerLogs" rule="RESOURCEMANAGER/resourcemanager/url/outbound"/>
+	            <apply path="amHostHttpAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+            </buffer>
+        </content>
+    </filter>
+
+    <filter name="RESOURCEMANAGER/resourcemanager/appattempts/outbound">
+        <content type="*/json">
+            <apply path="$.appAttempts.appAttempt[*].nodeHttpAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+            <apply path="$.appAttempts.appAttempt[*].logsLink" rule="RESOURCEMANAGER/resourcemanager/logsLink/outbound"/>
+            <apply path="$.appAttempts.appAttempt[*].nodeId" rule="RESOURCEMANAGER/resourcemanager/nodeId/outbound"/>
+        </content>
+        <content type="*/xml">
+            <apply path="/appAttempts/appAttempt/nodeHttpAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+            <apply path="/appAttempts/appAttempt/logsLink" rule="RESOURCEMANAGER/resourcemanager/logsLink/outbound"/>
+            <apply path="/appAttempts/appAttempt/nodeId" rule="RESOURCEMANAGER/resourcemanager/nodeId/outbound"/>
+        </content>
+    </filter>
+
+    <filter name="RESOURCEMANAGER/resourcemanager/nodes/outbound">
+        <content type="*/json">
+            <apply path="$.nodes.node[*].nodeHTTPAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+            <apply path="$.nodes.node[*].nodeHostName" rule="RESOURCEMANAGER/resourcemanager/host/outbound"/>
+            <apply path="$.nodes.node[*].id" rule="RESOURCEMANAGER/resourcemanager/nodeId/outbound"/>
+        </content>
+        <content type="*/xml">
+            <apply path="/nodes/node/nodeHTTPAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+            <apply path="/nodes/node/nodeHostName" rule="RESOURCEMANAGER/resourcemanager/host/outbound"/>
+            <apply path="/nodes/node/id" rule="RESOURCEMANAGER/resourcemanager/nodeId/outbound"/>
+        </content>
+    </filter>
+
+    <filter name="RESOURCEMANAGER/resourcemanager/node/outbound">
+        <content type="*/json">
+            <apply path="$.node.nodeHTTPAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+            <apply path="$.node.nodeHostName" rule="RESOURCEMANAGER/resourcemanager/host/outbound"/>
+            <apply path="$.node.id" rule="RESOURCEMANAGER/resourcemanager/nodeId/outbound"/>
+        </content>
+        <content type="*/xml">
+            <apply path="/node/nodeHTTPAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+            <apply path="/node/nodeHostName" rule="RESOURCEMANAGER/resourcemanager/host/outbound"/>
+            <apply path="/node/id" rule="RESOURCEMANAGER/resourcemanager/nodeId/outbound"/>
+        </content>
+    </filter>
+
+    <filter name="RESOURCEMANAGER/resourcemanager/proxy/jobattempts/outbound">
+        <content type="*/json">
+            <apply path="$.jobAttempts.jobAttempt[*].nodeHttpAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+            <apply path="$.jobAttempts.jobAttempt[*].nodeId" rule="RESOURCEMANAGER/resourcemanager/nodeId/outbound"/>
+            <apply path="$.jobAttempts.jobAttempt[*].logsLink" rule="RESOURCEMANAGER/resourcemanager/url/outbound"/>
+        </content>
+        <content type="*/xml">
+            <apply path="/jobAttempts/jobAttempt/nodeHttpAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+            <apply path="/jobAttempts/jobAttempt/nodeId" rule="RESOURCEMANAGER/resourcemanager/nodeId/outbound"/>
+            <apply path="/jobAttempts/jobAttempt/logsLink" rule="RESOURCEMANAGER/resourcemanager/url/outbound"/>
+        </content>
+    </filter>
+
+    <filter name="RESOURCEMANAGER/resourcemanager/proxy/taskattempts/outbound">
+        <content type="*/json">
+            <apply path="$.taskAttempts.taskAttempt[*].nodeHttpAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+        </content>
+        <content type="*/xml">
+            <apply path="/taskAttempts/taskAttempt/nodeHttpAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+        </content>
+    </filter>
+
+    <filter name="RESOURCEMANAGER/resourcemanager/proxy/taskattempt/outbound">
+        <content type="*/json">
+            <apply path="$.taskAttempt.nodeHttpAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+        </content>
+        <content type="*/xml">
+            <apply path="/taskAttempt/nodeHttpAddress" rule="RESOURCEMANAGER/resourcemanager/hostport/outbound"/>
+        </content>
+    </filter>
+
+</rules>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-service-yarn-rm/src/test/java/org/apache/hadoop/gateway/yarn/rm/ResourceManagerDeploymentContributorTest.java
----------------------------------------------------------------------
diff --git a/gateway-service-yarn-rm/src/test/java/org/apache/hadoop/gateway/yarn/rm/ResourceManagerDeploymentContributorTest.java b/gateway-service-yarn-rm/src/test/java/org/apache/hadoop/gateway/yarn/rm/ResourceManagerDeploymentContributorTest.java
new file mode 100644
index 0000000..485e1f2
--- /dev/null
+++ b/gateway-service-yarn-rm/src/test/java/org/apache/hadoop/gateway/yarn/rm/ResourceManagerDeploymentContributorTest.java
@@ -0,0 +1,45 @@
+/**
+ * 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.gateway.yarn.rm;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+import org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor;
+import org.junit.Test;
+
+public class ResourceManagerDeploymentContributorTest {
+
+  @SuppressWarnings("rawtypes")
+  @Test
+  public void testServiceLoader() throws Exception {
+    ServiceLoader loader = ServiceLoader.load( ServiceDeploymentContributor.class );
+    Iterator iterator = loader.iterator();
+    assertThat( "Service iterator empty.", iterator.hasNext() );
+    while( iterator.hasNext() ) {
+      Object object = iterator.next();
+      if( object instanceof ResourceManagerDeploymentContributor ) {
+        return;
+      }
+    }
+    fail( "Failed to find " + ResourceManagerDeploymentContributor.class.getName() + " via service loader." );
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/Shell.java
----------------------------------------------------------------------
diff --git a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/Shell.java b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/Shell.java
index 271b3cf..99c8b9a 100644
--- a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/Shell.java
+++ b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/Shell.java
@@ -45,6 +45,7 @@ public class Shell {
       setup.println( "import org.apache.hadoop.gateway.shell.hdfs.Hdfs;" );
       setup.println( "import org.apache.hadoop.gateway.shell.job.Job;" );
       setup.println( "import org.apache.hadoop.gateway.shell.workflow.Workflow;" );
+      setup.println( "import org.apache.hadoop.gateway.shell.yarn.Yarn;" );
       setup.println( "import java.util.concurrent.TimeUnit;" );
       //setup.println( "set verbosity QUIET;" );
       //setup.println( "set show-last-result false;" );

http://git-wip-us.apache.org/repos/asf/knox/blob/a970502a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/yarn/AppState.java
----------------------------------------------------------------------
diff --git a/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/yarn/AppState.java b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/yarn/AppState.java
new file mode 100644
index 0000000..b8a69ed
--- /dev/null
+++ b/gateway-shell/src/main/java/org/apache/hadoop/gateway/shell/yarn/AppState.java
@@ -0,0 +1,69 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.gateway.shell.yarn;
+
+import com.jayway.jsonpath.JsonPath;
+import org.apache.hadoop.gateway.shell.AbstractRequest;
+import org.apache.hadoop.gateway.shell.BasicResponse;
+import org.apache.hadoop.gateway.shell.Hadoop;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.utils.URIBuilder;
+
+import java.io.IOException;
+import java.util.concurrent.Callable;
+
+public class AppState {
+
+    static class Request extends AbstractRequest<Response> {
+
+        private String appId;
+
+        Request(Hadoop session) {
+            super(session);
+        }
+
+        public Request appId(String appId) {
+            this.appId = appId;
+            return this;
+        }
+
+        @Override
+        protected Callable<Response> callable() {
+            return new Callable<Response>() {
+                @Override
+                public Response call() throws Exception {
+                    URIBuilder uri = uri( Yarn.SERVICE_PATH, "/v1/cluster/apps/", appId, "/state" );
+                    HttpGet request = new HttpGet( uri.build() );
+                    return new Response( execute( request ) );
+                }
+            };
+        }
+    }
+
+    static class Response extends BasicResponse {
+
+        Response( HttpResponse response ) {
+            super( response );
+        }
+
+        public String getState() throws IOException {
+            return JsonPath.read(getString(), "$.state");
+        }
+    }
+}