knox-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From su...@apache.org
Subject [2/6] knox git commit: Combined commits done for KNOX-481, KNOX-483, KNOX-487
Date Thu, 12 Feb 2015 17:49:47 GMT
http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/AbstractGatewayDispatch.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/AbstractGatewayDispatch.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/AbstractGatewayDispatch.java
index 1bf5fc0..177ef8d 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/AbstractGatewayDispatch.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/AbstractGatewayDispatch.java
@@ -20,6 +20,7 @@ package org.apache.hadoop.gateway.dispatch;
 import org.apache.hadoop.gateway.filter.AbstractGatewayFilter;
 import org.apache.hadoop.gateway.filter.GatewayResponse;
 import org.apache.hadoop.io.IOUtils;
+import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpUriRequest;
 
 import javax.servlet.FilterChain;
@@ -38,48 +39,12 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-public abstract class AbstractGatewayDispatch extends AbstractGatewayFilter implements Dispatch {
+public abstract class AbstractGatewayDispatch implements Dispatch {
 
-  private static Map<String,Adapter> METHOD_ADAPTERS = createMethodAdapters();
   private static int STREAM_COPY_BUFFER_SIZE = 4096;
   private static final List<String> EXCLUDE_HEADERS = Arrays.asList( "Host", "Authorization", "Content-Length", "Transfer-Encoding" );
 
-  private static Map<String,Adapter> createMethodAdapters() {
-    Map<String,Adapter> map = new HashMap<String,Adapter>();
-    map.put( "GET", new GetAdapter() );
-    map.put( "POST", new PostAdapter() );
-    map.put( "PUT", new PutAdapter() );
-    map.put( "DELETE", new DeleteAdapter() );
-    map.put( "OPTIONS", new OptionsAdapter() );
-    return Collections.unmodifiableMap( map );
-  }
-
-  @Override
-  protected void doFilter( HttpServletRequest request, HttpServletResponse response, FilterChain chain )
-      throws IOException, ServletException {
-    String method = request.getMethod().toUpperCase();
-    Adapter adapter = METHOD_ADAPTERS.get( method );
-    if( adapter != null ) {
-      try {
-        adapter.doMethod( this, request, response );
-      } catch( URISyntaxException e ) {
-        throw new ServletException( e );
-      }
-    } else {
-      response.sendError( HttpServletResponse.SC_METHOD_NOT_ALLOWED );
-    }
-  }
-
-  protected static URI getDispatchUrl( HttpServletRequest request ) {
-    StringBuffer str = request.getRequestURL();
-    String query = request.getQueryString();
-    if( query != null ) {
-      str.append( '?' );
-      str.append( query );
-    }
-    URI url = URI.create( str.toString() );
-    return url;
-  }
+  protected  HttpClient client;
 
   protected void writeResponse( HttpServletRequest request, HttpServletResponse response, InputStream stream )
       throws IOException {
@@ -98,6 +63,16 @@ public abstract class AbstractGatewayDispatch extends AbstractGatewayFilter impl
 //    }
   }
 
+  @Override
+  public HttpClient getHttpClient() {
+    return client;
+  }
+
+  @Override
+  public void setHttpClient(HttpClient client) {
+    this.client = client;
+  }
+
   public void doGet( URI url, HttpServletRequest request, HttpServletResponse response )
       throws IOException, URISyntaxException {
     response.sendError( HttpServletResponse.SC_METHOD_NOT_ALLOWED );
@@ -122,46 +97,6 @@ public abstract class AbstractGatewayDispatch extends AbstractGatewayFilter impl
       throws IOException, URISyntaxException {
     response.sendError( HttpServletResponse.SC_METHOD_NOT_ALLOWED );
   }
-
-  private interface Adapter {
-    public void doMethod( Dispatch dispatch, HttpServletRequest request, HttpServletResponse response )
-        throws IOException, ServletException, URISyntaxException;
-  }
-
-  private static class GetAdapter implements Adapter {
-    public void doMethod( Dispatch dispatch, HttpServletRequest request, HttpServletResponse response )
-        throws IOException, ServletException, URISyntaxException {
-      dispatch.doGet( getDispatchUrl( request ), request, response );
-    }
-  }
-
-  private static class PostAdapter implements Adapter {
-    public void doMethod( Dispatch dispatch, HttpServletRequest request, HttpServletResponse response )
-        throws IOException, ServletException, URISyntaxException {
-      dispatch.doPost( getDispatchUrl( request ), request, response );
-    }
-  }
-
-  private static class PutAdapter implements Adapter {
-    public void doMethod( Dispatch dispatch, HttpServletRequest request, HttpServletResponse response )
-        throws IOException, ServletException, URISyntaxException {
-      dispatch.doPut( getDispatchUrl( request ), request, response );
-    }
-  }
-
-  private static class DeleteAdapter implements Adapter {
-    public void doMethod( Dispatch dispatch, HttpServletRequest request, HttpServletResponse response )
-        throws IOException, ServletException, URISyntaxException {
-      dispatch.doDelete( getDispatchUrl( request ), request, response );
-    }
-  }
-
-  private static class OptionsAdapter implements Adapter {
-    public void doMethod( Dispatch dispatch, HttpServletRequest request, HttpServletResponse response )
-        throws IOException, ServletException, URISyntaxException {
-      dispatch.doOptions( getDispatchUrl( request ), request, response );
-    }
-  }
   
   public static void copyRequestHeaderFields(HttpUriRequest outboundRequest,
       HttpServletRequest inboundRequest) {

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/Dispatch.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/Dispatch.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/Dispatch.java
index 072a2c6..0ce1339 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/Dispatch.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/Dispatch.java
@@ -17,6 +17,8 @@
  */
 package org.apache.hadoop.gateway.dispatch;
 
+import org.apache.http.client.HttpClient;
+
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -26,6 +28,14 @@ import java.net.URISyntaxException;
 
 public interface Dispatch {
 
+  void init();
+
+  void destroy();
+
+  HttpClient getHttpClient();
+
+  void setHttpClient(HttpClient httpClient);
+
   void doGet( URI url, HttpServletRequest request, HttpServletResponse response )
       throws IOException, ServletException, URISyntaxException;
 

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/GatewayDispatchFilter.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/GatewayDispatchFilter.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/GatewayDispatchFilter.java
new file mode 100644
index 0000000..f359568
--- /dev/null
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/GatewayDispatchFilter.java
@@ -0,0 +1,152 @@
+/**
+ * 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.dispatch;
+
+import org.apache.hadoop.gateway.filter.AbstractGatewayFilter;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.hadoop.gateway.config.ConfigurationInjectorBuilder.configuration;
+
+public class GatewayDispatchFilter extends AbstractGatewayFilter {
+
+  private static Map<String, Adapter> METHOD_ADAPTERS = createMethodAdapters();
+
+  private Dispatch dispatch;
+
+  private static Map<String, Adapter> createMethodAdapters() {
+    Map<String, Adapter> map = new HashMap<String, Adapter>();
+    map.put("GET", new GetAdapter());
+    map.put("POST", new PostAdapter());
+    map.put("PUT", new PutAdapter());
+    map.put("DELETE", new DeleteAdapter());
+    map.put("OPTIONS", new OptionsAdapter());
+    return Collections.unmodifiableMap(map);
+  }
+
+  @Override
+  public void init(FilterConfig filterConfig) throws ServletException {
+    super.init(filterConfig);
+    String dispatchImpl = filterConfig.getInitParameter("dispatch-impl");
+    dispatch = newDispatch(dispatchImpl);
+    configuration().target(dispatch).source(filterConfig).inject();
+    CloseableHttpClient client = HttpClients.createSystem();
+    //[sumit] this can perhaps be stashed in the servlet context to increase sharing of the client
+    dispatch.setHttpClient(client);
+    dispatch.init();
+  }
+
+  public Dispatch getDispatch() {
+    return dispatch;
+  }
+
+  public void setDispatch(Dispatch dispatch) {
+    this.dispatch = dispatch;
+  }
+
+  @Override
+  protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
+    String method = request.getMethod().toUpperCase();
+    Adapter adapter = METHOD_ADAPTERS.get(method);
+    if ( adapter != null ) {
+      try {
+        adapter.doMethod(dispatch, request, response);
+      } catch ( URISyntaxException e ) {
+        throw new ServletException(e);
+      }
+    } else {
+      response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
+    }
+  }
+
+  protected static URI getDispatchUrl(HttpServletRequest request) {
+    StringBuffer str = request.getRequestURL();
+    String query = request.getQueryString();
+    if ( query != null ) {
+      str.append('?');
+      str.append(query);
+    }
+    URI url = URI.create(str.toString());
+    return url;
+  }
+
+  private interface Adapter {
+    public void doMethod(Dispatch dispatch, HttpServletRequest request, HttpServletResponse response)
+        throws IOException, ServletException, URISyntaxException;
+  }
+
+  private static class GetAdapter implements Adapter {
+    public void doMethod(Dispatch dispatch, HttpServletRequest request, HttpServletResponse response)
+        throws IOException, ServletException, URISyntaxException {
+      dispatch.doGet(getDispatchUrl(request), request, response);
+    }
+  }
+
+  private static class PostAdapter implements Adapter {
+    public void doMethod(Dispatch dispatch, HttpServletRequest request, HttpServletResponse response)
+        throws IOException, ServletException, URISyntaxException {
+      dispatch.doPost(getDispatchUrl(request), request, response);
+    }
+  }
+
+  private static class PutAdapter implements Adapter {
+    public void doMethod(Dispatch dispatch, HttpServletRequest request, HttpServletResponse response)
+        throws IOException, ServletException, URISyntaxException {
+      dispatch.doPut(getDispatchUrl(request), request, response);
+    }
+  }
+
+  private static class DeleteAdapter implements Adapter {
+    public void doMethod(Dispatch dispatch, HttpServletRequest request, HttpServletResponse response)
+        throws IOException, ServletException, URISyntaxException {
+      dispatch.doDelete(getDispatchUrl(request), request, response);
+    }
+  }
+
+  private static class OptionsAdapter implements Adapter {
+    public void doMethod(Dispatch dispatch, HttpServletRequest request, HttpServletResponse response)
+        throws IOException, ServletException, URISyntaxException {
+      dispatch.doOptions(getDispatchUrl(request), request, response);
+    }
+  }
+
+  private Dispatch newDispatch(String dispatchImpl) throws ServletException {
+    try {
+      ClassLoader loader = Thread.currentThread().getContextClassLoader();
+      if ( loader == null ) {
+        loader = this.getClass().getClassLoader();
+      }
+      Class<Dispatch> clazz = (Class) loader.loadClass(dispatchImpl);
+      return clazz.newInstance();
+    } catch ( Exception e ) {
+      throw new ServletException(e);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/HttpClientDispatch.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/HttpClientDispatch.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/HttpClientDispatch.java
index 4de9730..e5810d4 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/HttpClientDispatch.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/dispatch/HttpClientDispatch.java
@@ -35,6 +35,8 @@ import org.apache.hadoop.gateway.audit.api.AuditServiceFactory;
 import org.apache.hadoop.gateway.audit.api.Auditor;
 import org.apache.hadoop.gateway.audit.api.ResourceType;
 import org.apache.hadoop.gateway.audit.log4j.audit.AuditConstants;
+import org.apache.hadoop.gateway.config.Configure;
+import org.apache.hadoop.gateway.config.Default;
 import org.apache.hadoop.gateway.config.GatewayConfig;
 import org.apache.hadoop.gateway.i18n.messages.MessagesFactory;
 import org.apache.hadoop.gateway.i18n.resources.ResourcesFactory;
@@ -43,6 +45,7 @@ import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
 import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpClient;
 import org.apache.http.client.methods.HttpDelete;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpOptions;
@@ -59,43 +62,39 @@ import org.apache.http.message.BasicHeader;
  */
 public class HttpClientDispatch extends AbstractGatewayDispatch {
 
-   private static final String REPLAY_BUFFER_SIZE = "replayBufferSize";
+  // private static final String CT_APP_WWW_FORM_URL_ENCODED = "application/x-www-form-urlencoded";
+  // private static final String CT_APP_XML = "application/xml";
+  protected static final String Q_DELEGATION_EQ = "?delegation=";
+  protected static final String AMP_DELEGATION_EQ = "&delegation=";
+  protected static final String COOKIE = "Cookie";
+  protected static final String SET_COOKIE = "Set-Cookie";
+  protected static final String WWW_AUTHENTICATE = "WWW-Authenticate";
+  protected static final String NEGOTIATE = "Negotiate";
 
-   // private static final String CT_APP_WWW_FORM_URL_ENCODED = "application/x-www-form-urlencoded";
-   // private static final String CT_APP_XML = "application/xml";
-   protected static final String Q_DELEGATION_EQ = "?delegation=";
-   protected static final String AMP_DELEGATION_EQ = "&delegation=";
-   protected static final String COOKIE = "Cookie";
-   protected static final String SET_COOKIE = "Set-Cookie";
-   protected static final String WWW_AUTHENTICATE = "WWW-Authenticate";
-   protected static final String NEGOTIATE = "Negotiate";
+  protected static SpiGatewayMessages LOG = MessagesFactory.get(SpiGatewayMessages.class);
+  protected static SpiGatewayResources RES = ResourcesFactory.get(SpiGatewayResources.class);
+  protected static Auditor auditor = AuditServiceFactory.getAuditService().getAuditor(AuditConstants.DEFAULT_AUDITOR_NAME,
+      AuditConstants.KNOX_SERVICE_NAME, AuditConstants.KNOX_COMPONENT_NAME);
 
-   protected static SpiGatewayMessages LOG = MessagesFactory.get(SpiGatewayMessages.class);
-   protected static SpiGatewayResources RES = ResourcesFactory.get(SpiGatewayResources.class);
-   protected static Auditor auditor = AuditServiceFactory.getAuditService().getAuditor(AuditConstants.DEFAULT_AUDITOR_NAME,
-         AuditConstants.KNOX_SERVICE_NAME, AuditConstants.KNOX_COMPONENT_NAME);
+  protected AppCookieManager appCookieManager;
 
-   protected AppCookieManager appCookieManager;
+  private int replayBufferSize = 0;
 
-   protected static final String REPLAY_BUFFER_SIZE_PARAM = "replayBufferSize";
+  @Override
+  public void init() {
+    setAppCookieManager(new AppCookieManager());
+  }
 
-   private int replayBufferSize = 0;
+  @Override
+  public void destroy() {
 
-   @Override
-   public void init(FilterConfig filterConfig) throws ServletException {
-      this.init(filterConfig, new AppCookieManager());
-   }
+  }
 
-   protected void init(FilterConfig filterConfig, AppCookieManager cookieManager) throws ServletException {
-      super.init(filterConfig);
-      appCookieManager = cookieManager;
-      String replayBufferSizeString = filterConfig.getInitParameter(REPLAY_BUFFER_SIZE_PARAM);
-      if (replayBufferSizeString != null) {
-         setReplayBufferSize(Integer.valueOf(replayBufferSizeString));
-      }
-   }
+  public void setAppCookieManager(AppCookieManager appCookieManager) {
+    this.appCookieManager = appCookieManager;
+  }
 
-   protected void executeRequest(
+  protected void executeRequest(
          HttpUriRequest outboundRequest,
          HttpServletRequest inboundRequest,
          HttpServletResponse outboundResponse)
@@ -107,7 +106,6 @@ public class HttpClientDispatch extends AbstractGatewayDispatch {
    protected HttpResponse executeOutboundRequest(HttpUriRequest outboundRequest) throws IOException {
       LOG.dispatchRequest(outboundRequest.getMethod(), outboundRequest.getURI());
       HttpResponse inboundResponse = null;
-      DefaultHttpClient client = new DefaultHttpClient();
 
       try {
          String query = outboundRequest.getURI().getQuery();
@@ -190,7 +188,7 @@ public class HttpClientDispatch extends AbstractGatewayDispatch {
    }
 
    protected HttpResponse executeKerberosDispatch(HttpUriRequest outboundRequest,
-                                                  DefaultHttpClient client) throws IOException, ClientProtocolException {
+                                                  HttpClient client) throws IOException, ClientProtocolException {
       HttpResponse inboundResponse;
       outboundRequest.removeHeaders(COOKIE);
       String appCookie = appCookieManager.getCachedAppCookie();
@@ -302,7 +300,8 @@ public class HttpClientDispatch extends AbstractGatewayDispatch {
       return replayBufferSize;
    }
 
-   protected void setReplayBufferSize(int size) {
+   @Configure
+   protected void setReplayBufferSize(@Default("8") int size) {
       replayBufferSize = size;
    }
 

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Service.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Service.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Service.java
index 9763174..41270a9 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Service.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Service.java
@@ -27,6 +27,7 @@ public class Service {
 
   private String role;
   private String name;
+  private Version version;
   private Map<String, String> params = new LinkedHashMap<String, String>();
   private List<String> urls;
 
@@ -46,6 +47,14 @@ public class Service {
     this.name = name;
   }
 
+  public Version getVersion() {
+    return version;
+  }
+
+  public void setVersion(Version version) {
+    this.version = version;
+  }
+
   public List<String> getUrls() {
     if ( urls == null ) {
       urls = new ArrayList<String>();

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Topology.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Topology.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Topology.java
index c8d611d..2f5d671 100644
--- a/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Topology.java
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Topology.java
@@ -17,12 +17,11 @@
  */
 package org.apache.hadoop.gateway.topology;
 
+import org.apache.commons.collections.map.HashedMap;
+import org.apache.commons.collections.map.MultiKeyMap;
+
 import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 public class Topology {
 
@@ -32,7 +31,12 @@ public class Topology {
   public List<Provider> providerList = new ArrayList<Provider>();
   private Map<String,Map<String,Provider>> providerMap = new HashMap<String,Map<String,Provider>>();
   public List<Service> services = new ArrayList<Service>();
-  private Map<String, Map<String, Service>> serviceMap = new HashMap<String, Map<String, Service>>();
+
+  private MultiKeyMap serviceMap;
+
+  public Topology() {
+    serviceMap = MultiKeyMap.decorate(new HashedMap());
+  }
 
   public URI getUri() {
     return uri;
@@ -62,27 +66,13 @@ public class Topology {
     return services;
   }
 
-  public Service getService( String role, String name ) {
-    Service service = null;
-    Map<String, Service> nameMap = serviceMap.get( role );
-    if( nameMap != null) {
-      service = nameMap.get( name );
-      if ( service == null && !nameMap.values().isEmpty() ) {
-        service = (Service) nameMap.values().toArray()[0];
-      }
-    }
-    return service;
+  public Service getService(String role, String name, Version version) {
+    return (Service)serviceMap.get(role, name, version);
   }
 
   public void addService( Service service ) {
     services.add( service );
-    String role = service.getRole();
-    Map<String, Service> nameMap = serviceMap.get( role );
-    if( nameMap == null ) {
-      nameMap = new HashMap<String, Service>();
-      serviceMap.put( role, nameMap );
-    }
-    nameMap.put( service.getName(), service );
+    serviceMap.put(service.getRole(), service.getName(), service.getVersion(), service);
   }
 
   public Collection<Provider> getProviders() {

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Version.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Version.java b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Version.java
new file mode 100644
index 0000000..08aca08
--- /dev/null
+++ b/gateway-spi/src/main/java/org/apache/hadoop/gateway/topology/Version.java
@@ -0,0 +1,130 @@
+/**
+ * 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.topology;
+
+public class Version implements Comparable<Version> {
+
+  private int major;
+
+  private int minor;
+
+  private int patch;
+
+  public Version() {
+  }
+
+  public Version(String version) {
+    setVersion(version);
+  }
+
+  public Version(int major, int minor, int patch) {
+    this.major = major;
+    this.minor = minor;
+    this.patch = patch;
+  }
+
+  public int getMajor() {
+    return major;
+  }
+
+  public void setMajor(int major) {
+    this.major = major;
+  }
+
+  public int getMinor() {
+    return minor;
+  }
+
+  public void setMinor(int minor) {
+    this.minor = minor;
+  }
+
+  public int getPatch() {
+    return patch;
+  }
+
+  public void setPatch(int patch) {
+    this.patch = patch;
+  }
+
+  public void setVersion(String version) {
+    if (version != null) {
+      parseVersion(version);
+    }
+  }
+
+  private void parseVersion(String version) {
+    String parts[] = version.split("\\.");
+    int length = parts.length;
+    if (length >= 1) {
+      major = Integer.parseInt(parts[0]);
+    }
+    if (length >= 2) {
+      minor = Integer.parseInt(parts[1]);
+    }
+    if (length >= 3) {
+      patch = Integer.parseInt(parts[2]);
+    }
+  }
+
+  @Override
+  public int compareTo(Version version) {
+    if (major > version.getMajor()) {
+      return 1;
+    }
+    if (major < version.getMajor()) {
+      return -1;
+    }
+    if (minor > version.getMinor()) {
+      return 1;
+    }
+    if (minor < version.getMinor()) {
+      return -1;
+    }
+    if (patch > version.getPatch()) {
+      return 1;
+    }
+    if (patch < version.getPatch()) {
+      return -1;
+    }
+    return 0;
+  }
+
+  @Override
+  public String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer.append(major);
+    buffer.append(".");
+    buffer.append(minor);
+    buffer.append(".");
+    buffer.append(patch);
+    return buffer.toString();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (!(o instanceof Version)) {
+      return false;
+    }
+    Version that = (Version) o;
+    if (major == that.getMajor() && minor == that.getMinor() && patch == that.getPatch()) {
+      return true;
+    }
+    return false;
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-spi/src/main/resources/META-INF/services/org.apache.hadoop.gateway.config.spi.ConfigurationAdapterDescriptor
----------------------------------------------------------------------
diff --git a/gateway-spi/src/main/resources/META-INF/services/org.apache.hadoop.gateway.config.spi.ConfigurationAdapterDescriptor b/gateway-spi/src/main/resources/META-INF/services/org.apache.hadoop.gateway.config.spi.ConfigurationAdapterDescriptor
new file mode 100755
index 0000000..4c1cad9
--- /dev/null
+++ b/gateway-spi/src/main/resources/META-INF/services/org.apache.hadoop.gateway.config.spi.ConfigurationAdapterDescriptor
@@ -0,0 +1,18 @@
+##########################################################################
+# 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.config.FilterConfigurationAdapterDescriptor

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-spi/src/test/java/org/apache/hadoop/gateway/dispatch/HttpClientDispatchTest.java
----------------------------------------------------------------------
diff --git a/gateway-spi/src/test/java/org/apache/hadoop/gateway/dispatch/HttpClientDispatchTest.java b/gateway-spi/src/test/java/org/apache/hadoop/gateway/dispatch/HttpClientDispatchTest.java
index b9b26b6..9446ab5 100644
--- a/gateway-spi/src/test/java/org/apache/hadoop/gateway/dispatch/HttpClientDispatchTest.java
+++ b/gateway-spi/src/test/java/org/apache/hadoop/gateway/dispatch/HttpClientDispatchTest.java
@@ -39,6 +39,7 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.hadoop.gateway.config.GatewayConfig;
 import org.apache.http.HttpEntity;
 import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.impl.client.DefaultHttpClient;
 import org.apache.http.params.BasicHttpParams;
 import org.easymock.EasyMock;
 import org.easymock.IAnswer;
@@ -76,6 +77,7 @@ public class HttpClientDispatchTest {
     EasyMock.replay( outboundRequest, inboundRequest, outboundResponse );
 
     HttpClientDispatch dispatch = new HttpClientDispatch();
+    dispatch.setHttpClient(new DefaultHttpClient());
     try {
       dispatch.executeRequest( outboundRequest, inboundRequest, outboundResponse );
       fail( "Should have thrown IOException" );

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayFuncTestDriver.java
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayFuncTestDriver.java b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayFuncTestDriver.java
index 6faccac..6117c76 100644
--- a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayFuncTestDriver.java
+++ b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayFuncTestDriver.java
@@ -157,6 +157,18 @@ public class GatewayFuncTestDriver {
     } catch (ServiceLifecycleException e) {
       e.printStackTrace(); // I18N not required.
     }
+    File stacksDir = new File( config.getGatewayStacksDir() );
+    stacksDir.mkdirs();
+    //TODO: [sumit] This is a hack for now, need to find a better way to locate the source resources for 'stacks' to be tested
+    String pathToStacksSource = "gateway-service-definitions/src/main/resources/services";
+    File stacksSourceDir = new File( targetDir.getParent(), pathToStacksSource);
+    if (!stacksSourceDir.exists()) {
+      stacksSourceDir = new File( targetDir.getParentFile().getParent(), pathToStacksSource);
+    }
+    if (stacksSourceDir.exists()) {
+      FileUtils.copyDirectoryToDirectory(stacksSourceDir, stacksDir);
+    }
+
     gateway = GatewayServer.startGateway( config, srvcs );
     MatcherAssert.assertThat( "Failed to start gateway.", gateway, notNullValue() );
 
@@ -170,6 +182,7 @@ public class GatewayFuncTestDriver {
     FileUtils.deleteQuietly( new File( config.getGatewaySecurityDir() ) );
     FileUtils.deleteQuietly( new File( config.getGatewayDeploymentDir() ) );
     FileUtils.deleteQuietly( new File( config.getGatewayDataDir() ) );
+    FileUtils.deleteQuietly( new File( config.getGatewayStacksDir() ) );
 
     for( Service service : services.values() ) {
       service.server.stop();

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
index a013505..259ff09 100644
--- a/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
+++ b/gateway-test/src/test/java/org/apache/hadoop/gateway/GatewayTestConfig.java
@@ -189,5 +189,9 @@ public class GatewayTestConfig implements GatewayConfig {
 //  public void setKerberosLoginConfig(String kerberosLoginConfig) {
 //   this.kerberosLoginConfig = kerberosLoginConfig;
 //  }
-  
+
+   @Override
+   public String getGatewayStacksDir() {
+      return gatewayHomeDir + "/data/services";
+   }
 }

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-test/src/test/java/org/apache/hadoop/gateway/deploy/DeploymentFactoryFuncTest.java
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/java/org/apache/hadoop/gateway/deploy/DeploymentFactoryFuncTest.java b/gateway-test/src/test/java/org/apache/hadoop/gateway/deploy/DeploymentFactoryFuncTest.java
index fc699b1..8b54f6f 100644
--- a/gateway-test/src/test/java/org/apache/hadoop/gateway/deploy/DeploymentFactoryFuncTest.java
+++ b/gateway-test/src/test/java/org/apache/hadoop/gateway/deploy/DeploymentFactoryFuncTest.java
@@ -82,6 +82,7 @@ public class DeploymentFactoryFuncTest {
 
 //    ((GatewayTestConfig) config).setDeploymentDir( "clusters" );
 
+    addStacksDir(config, targetDir);
     DefaultGatewayServices srvcs = new DefaultGatewayServices();
     Map<String,String> options = new HashMap<String,String>();
     options.put("persist-master", "false");
@@ -135,6 +136,7 @@ public class DeploymentFactoryFuncTest {
     ((GatewayTestConfig) config).setGatewayHomeDir( gatewayDir.getAbsolutePath() );
     File deployDir = new File( config.getGatewayDeploymentDir() );
     deployDir.mkdirs();
+    addStacksDir(config, targetDir);
 
     DefaultGatewayServices srvcs = new DefaultGatewayServices();
     Map<String,String> options = new HashMap<String,String>();
@@ -189,6 +191,7 @@ public class DeploymentFactoryFuncTest {
     ((GatewayTestConfig) config).setGatewayHomeDir( gatewayDir.getAbsolutePath() );
     File deployDir = new File( config.getGatewayDeploymentDir() );
     deployDir.mkdirs();
+    addStacksDir(config, targetDir);
 
     DefaultGatewayServices srvcs = new DefaultGatewayServices();
     Map<String,String> options = new HashMap<String,String>();
@@ -228,8 +231,8 @@ public class DeploymentFactoryFuncTest {
     topology.addProvider( authorizer );
 
     WebArchive war = DeploymentFactory.createDeployment( config, topology );
-    //File dir = new File( System.getProperty( "user.dir" ) );
-    //File file = war.as( ExplodedExporter.class ).exportExploded( dir, "test-cluster.war" );
+//    File dir = new File( System.getProperty( "user.dir" ) );
+//    File file = war.as( ExplodedExporter.class ).exportExploded( dir, "test-cluster.war" );
 
     Document web = parse( war.get( "WEB-INF/web.xml" ).getAsset().openStream() );
     assertThat( web, hasXPath( "/web-app/servlet/servlet-name", equalTo( "test-cluster" ) ) );
@@ -264,8 +267,8 @@ public class DeploymentFactoryFuncTest {
     assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[6]/class", equalTo( "org.apache.hadoop.gateway.filter.AclsAuthorizationFilter" ) ) );
 
     assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[7]/role", equalTo( "dispatch" ) ) );
-    assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[7]/name", equalTo( "hdfs" ) ) );
-    assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[7]/class", equalTo( "org.apache.hadoop.gateway.hdfs.dispatch.HdfsDispatch" ) ) );
+    assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[7]/name", equalTo( "webhdfs" ) ) );
+    assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[7]/class", equalTo( "org.apache.hadoop.gateway.dispatch.GatewayDispatchFilter" ) ) );
 
     assertThat( gateway, hasXPath( "/gateway/resource[2]/pattern", equalTo( "/webhdfs/v1/**?**" ) ) );
     //assertThat( gateway, hasXPath( "/gateway/resource[2]/target", equalTo( "http://localhost:50070/webhdfs/v1/{path=**}?{**}" ) ) );
@@ -290,8 +293,8 @@ public class DeploymentFactoryFuncTest {
     assertThat( gateway, hasXPath( "/gateway/resource[1]/filter[6]/class", equalTo( "org.apache.hadoop.gateway.filter.AclsAuthorizationFilter" ) ) );
 
     assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[7]/role", equalTo( "dispatch" ) ) );
-    assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[7]/name", equalTo( "hdfs" ) ) );
-    assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[7]/class", equalTo( "org.apache.hadoop.gateway.hdfs.dispatch.HdfsDispatch" ) ) );
+    assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[7]/name", equalTo( "webhdfs" ) ) );
+    assertThat( gateway, hasXPath( "/gateway/resource[2]/filter[7]/class", equalTo( "org.apache.hadoop.gateway.dispatch.GatewayDispatchFilter" ) ) );
   }
 
 
@@ -379,6 +382,7 @@ public class DeploymentFactoryFuncTest {
     ((GatewayTestConfig) config).setGatewayHomeDir(gatewayDir.getAbsolutePath());
     File deployDir = new File(config.getGatewayDeploymentDir());
     deployDir.mkdirs();
+    addStacksDir(config, targetDir);
 
     DefaultGatewayServices srvcs = new DefaultGatewayServices();
     Map<String, String> options = new HashMap<String, String>();
@@ -453,6 +457,7 @@ public class DeploymentFactoryFuncTest {
     ((GatewayTestConfig) config).setGatewayHomeDir(gatewayDir.getAbsolutePath());
     File deployDir = new File(config.getGatewayDeploymentDir());
     deployDir.mkdirs();
+    addStacksDir(config, targetDir);
 
     DefaultGatewayServices srvcs = new DefaultGatewayServices();
     Map<String, String> options = new HashMap<String, String>();
@@ -499,7 +504,7 @@ public class DeploymentFactoryFuncTest {
 
     WebArchive war = DeploymentFactory.createDeployment( config, topology );
     Document doc = parse( war.get( "WEB-INF/gateway.xml" ).getAsset().openStream() );
-    //dump( doc );
+    dump( doc );
 
     Node resourceNode, filterNode, paramNode;
     String value;
@@ -538,6 +543,33 @@ public class DeploymentFactoryFuncTest {
     return builder.parse( source );
   }
 
+  private void addStacksDir(GatewayConfig config, File targetDir) {
+    File stacksDir = new File( config.getGatewayStacksDir() );
+    stacksDir.mkdirs();
+    //TODO: [sumit] This is a hack for now, need to find a better way to locate the source resources for 'stacks' to be tested
+    String pathToStacksSource = "gateway-service-definitions/src/main/resources/services";
+    File stacksSourceDir = new File( targetDir.getParent(), pathToStacksSource);
+    if (!stacksSourceDir.exists()) {
+      stacksSourceDir = new File( targetDir.getParentFile().getParent(), pathToStacksSource);
+    }
+    if (stacksSourceDir.exists()) {
+      try {
+        FileUtils.copyDirectoryToDirectory(stacksSourceDir, stacksDir);
+      } catch ( IOException e) {
+        fail(e.getMessage());
+      }
+    }
+
+  }
+//  private void dump( Document document ) throws TransformerException {
+//    Transformer transformer = TransformerFactory.newInstance().newTransformer();
+//    transformer.setOutputProperty( OutputKeys.INDENT, "yes" );
+//    StreamResult result = new StreamResult( new StringWriter() );
+//    DOMSource source = new DOMSource( document );
+//    transformer.transform( source, result );
+//    String xmlString = result.getWriter().toString();
+//    System.out.println( xmlString );
+//  }
   private void dump( Document document ) throws TransformerException {
     Transformer transformer = TransformerFactory.newInstance().newTransformer();
     transformer.setOutputProperty( OutputKeys.INDENT, "yes" );

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-test/src/test/java/org/apache/hadoop/gateway/webhcat/WebHCatDeploymentContributorTest.java
----------------------------------------------------------------------
diff --git a/gateway-test/src/test/java/org/apache/hadoop/gateway/webhcat/WebHCatDeploymentContributorTest.java b/gateway-test/src/test/java/org/apache/hadoop/gateway/webhcat/WebHCatDeploymentContributorTest.java
deleted file mode 100644
index 8b3303d..0000000
--- a/gateway-test/src/test/java/org/apache/hadoop/gateway/webhcat/WebHCatDeploymentContributorTest.java
+++ /dev/null
@@ -1,45 +0,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.
- */
-package org.apache.hadoop.gateway.webhcat;
-
-import org.apache.hadoop.gateway.deploy.ServiceDeploymentContributor;
-import org.junit.Test;
-
-import java.util.Iterator;
-import java.util.ServiceLoader;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.fail;
-
-public class WebHCatDeploymentContributorTest {
-
-  @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 WebHCatDeploymentContributor ) {
-        return;
-      }
-    }
-    fail( "Failed to find " + WebHCatDeploymentContributor.class.getName() + " via service loader." );
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/pom.xml
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/pom.xml b/gateway-util-configinjector/pom.xml
new file mode 100755
index 0000000..b247e99
--- /dev/null
+++ b/gateway-util-configinjector/pom.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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 xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.knox</groupId>
+        <artifactId>gateway</artifactId>
+        <version>0.6.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>gateway-util-configinjector</artifactId>
+
+    <name>gateway-util-configinjector</name>
+    <description>A lightweight config injection utility</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>commons-beanutils</groupId>
+            <artifactId>commons-beanutils</artifactId>
+            <scope>compile</scope>
+            <version>1.9.2</version>
+        </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>
+        <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>
+    </dependencies>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Alias.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Alias.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Alias.java
new file mode 100755
index 0000000..b002e7a
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Alias.java
@@ -0,0 +1,31 @@
+/**
+ * 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.config;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target( { ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER} )
+@Retention( RetentionPolicy.RUNTIME )
+@Documented
+public @interface Alias {
+  public String value();
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationAdapter.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationAdapter.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationAdapter.java
new file mode 100755
index 0000000..401258f
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationAdapter.java
@@ -0,0 +1,24 @@
+/**
+ * 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.config;
+
+public interface ConfigurationAdapter {
+
+  Object getConfigurationValue(String name) throws ConfigurationException;
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationBinding.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationBinding.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationBinding.java
new file mode 100755
index 0000000..a2b2b67
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationBinding.java
@@ -0,0 +1,24 @@
+/**
+ * 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.config;
+
+public interface ConfigurationBinding {
+
+  String getConfigurationName(String name);
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationException.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationException.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationException.java
new file mode 100755
index 0000000..c979cc6
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationException.java
@@ -0,0 +1,30 @@
+/**
+ * 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.config;
+
+public class ConfigurationException extends RuntimeException {
+
+  public ConfigurationException( String message, Throwable cause ) {
+    super( message, cause );
+  }
+
+  public ConfigurationException( String message ) {
+    super( message );
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationInjectorBuilder.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationInjectorBuilder.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationInjectorBuilder.java
new file mode 100755
index 0000000..e0fadbd
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/ConfigurationInjectorBuilder.java
@@ -0,0 +1,107 @@
+/**
+ * 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.config;
+
+import org.apache.hadoop.gateway.config.impl.ConfigurationAdapterFactory;
+import org.apache.hadoop.gateway.config.impl.DefaultConfigurationBinding;
+import org.apache.hadoop.gateway.config.impl.MappedConfigurationBinding;
+import org.apache.hadoop.gateway.config.spi.ConfigurationInjector;
+
+import java.util.Iterator;
+import java.util.ServiceLoader;
+
+public class ConfigurationInjectorBuilder {
+
+  private static ConfigurationBinding DEFAULT_BINDING = new DefaultConfigurationBinding();
+  private static ConfigurationInjector INSTANCE = null;
+
+  private static synchronized ConfigurationInjector getInjector() {
+    if( INSTANCE == null ) {
+      INSTANCE = createInjector();
+    }
+    return INSTANCE;
+  }
+
+  private static synchronized ConfigurationInjector createInjector() {
+    ConfigurationInjector injector = null;
+    ServiceLoader<ConfigurationInjector> loader = ServiceLoader.load( ConfigurationInjector.class );
+    if( loader != null ) {
+      Iterator<ConfigurationInjector> iterator = loader.iterator();
+      if( iterator != null ) {
+        while( iterator.hasNext() ) {
+          injector = iterator.next();
+          break;
+        }
+      }
+    }
+    if( injector == null ) {
+      throw new ConfigurationException( String.format(
+          "Failed to load an implementation of %s", ConfigurationInjector.class.getName() ) );
+    }
+    return injector;
+  }
+
+  private Object target = null;
+  private ConfigurationAdapter source = null;
+  private ConfigurationBinding binding = null;
+
+  public static ConfigurationInjectorBuilder configuration() {
+    return new ConfigurationInjectorBuilder();
+  }
+
+  public ConfigurationInjectorBuilder target( Object target ) {
+    this.target = target;
+    return this;
+  }
+
+  public ConfigurationInjectorBuilder source( Object source ) {
+    this.source = ConfigurationAdapterFactory.get(source);
+    return this;
+  }
+
+  public ConfigurationInjectorBuilder source( ConfigurationAdapter adapter ) {
+    this.source = adapter;
+    return this;
+  }
+
+  public ConfigurationInjectorBuilder binding( ConfigurationBinding binding ) {
+    this.binding = binding;
+    return this;
+  }
+
+  public ConfigurationInjectorBuilder bind( String targetName, String sourceName ) {
+    ((MappedConfigurationBinding)binding()).bind( targetName, sourceName );
+    return this;
+  }
+
+  public ConfigurationBinding binding() {
+    if( binding == null ) {
+      binding = new MappedConfigurationBinding();
+    }
+    return binding;
+  }
+
+  public void inject() throws ConfigurationException {
+    ConfigurationInjector injector = getInjector();
+    if( binding == null ) {
+      binding = DEFAULT_BINDING;
+    }
+    injector.configure( target, source, binding );
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Configure.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Configure.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Configure.java
new file mode 100755
index 0000000..895648f
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Configure.java
@@ -0,0 +1,30 @@
+/**
+ * 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.config;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target( { ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER} )
+@Retention( RetentionPolicy.RUNTIME )
+@Documented
+public @interface Configure {
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Default.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Default.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Default.java
new file mode 100755
index 0000000..1ef9042
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Default.java
@@ -0,0 +1,31 @@
+/**
+ * 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.config;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target( { ElementType.PARAMETER } )
+@Retention( RetentionPolicy.RUNTIME )
+@Documented
+public @interface Default {
+  public String value();
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Optional.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Optional.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Optional.java
new file mode 100755
index 0000000..1299e75
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/Optional.java
@@ -0,0 +1,30 @@
+/**
+ * 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.config;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target( { ElementType.FIELD } )
+@Retention( RetentionPolicy.RUNTIME )
+@Documented
+public @interface Optional {
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/BeanConfigurationAdapter.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/BeanConfigurationAdapter.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/BeanConfigurationAdapter.java
new file mode 100755
index 0000000..67459a4
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/BeanConfigurationAdapter.java
@@ -0,0 +1,40 @@
+/**
+ * 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.config.impl;
+
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.hadoop.gateway.config.ConfigurationAdapter;
+import org.apache.hadoop.gateway.config.ConfigurationException;
+
+public class BeanConfigurationAdapter implements ConfigurationAdapter {
+
+  private Object bean;
+
+  public BeanConfigurationAdapter( Object bean ) {
+    this.bean = bean;
+  }
+
+  @Override
+  public Object getConfigurationValue( String name ) throws ConfigurationException {
+    try {
+      return PropertyUtils.getSimpleProperty( bean, name );
+    } catch( Exception e ) {
+      throw new ConfigurationException( String.format( "" ), e );
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/BeanConfigurationAdapterDescriptor.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/BeanConfigurationAdapterDescriptor.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/BeanConfigurationAdapterDescriptor.java
new file mode 100755
index 0000000..92a6cca
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/BeanConfigurationAdapterDescriptor.java
@@ -0,0 +1,30 @@
+/**
+ * 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.config.impl;
+
+import org.apache.hadoop.gateway.config.spi.AbstractConfigurationAdapterDescriptor;
+
+import java.util.Map;
+
+public class BeanConfigurationAdapterDescriptor extends AbstractConfigurationAdapterDescriptor {
+
+  public BeanConfigurationAdapterDescriptor() {
+    add( Object.class, BeanConfigurationAdapter.class );
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/ConfigurationAdapterFactory.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/ConfigurationAdapterFactory.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/ConfigurationAdapterFactory.java
new file mode 100755
index 0000000..73cd97b
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/ConfigurationAdapterFactory.java
@@ -0,0 +1,132 @@
+/**
+ * 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.config.impl;
+
+
+import org.apache.hadoop.gateway.config.ConfigurationAdapter;
+import org.apache.hadoop.gateway.config.ConfigurationException;
+import org.apache.hadoop.gateway.config.spi.ConfigurationAdapterDescriptor;
+
+import java.lang.reflect.Constructor;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.ServiceLoader;
+
+public class ConfigurationAdapterFactory {
+
+  private static Map<Class<?>, Class<? extends ConfigurationAdapter>> ADAPTERS = null;
+
+  private static synchronized Map<Class<?>, Class<? extends ConfigurationAdapter>> getAdapters() {
+    if( ADAPTERS == null ) {
+      loadAdapters();
+    }
+    return ADAPTERS;
+  }
+
+  private static void loadAdapters() {
+    Map<Class<?>, Class<? extends ConfigurationAdapter>> all =
+        new HashMap<Class<?>, Class<? extends ConfigurationAdapter>>();
+    ServiceLoader<ConfigurationAdapterDescriptor> loader = ServiceLoader.load( ConfigurationAdapterDescriptor.class );
+    if( loader != null ) {
+      Iterator<ConfigurationAdapterDescriptor> i = loader.iterator();
+      if( i != null ) {
+        while( i.hasNext() ) {
+          ConfigurationAdapterDescriptor descriptor = i.next();
+          Map<Class<?>, Class<? extends ConfigurationAdapter>> add = descriptor.providedConfigurationAdapters();
+          if( add != null ) {
+            all.putAll( add );
+          }
+        }
+      }
+    }
+    ADAPTERS = Collections.unmodifiableMap( all );
+  }
+
+  public static ConfigurationAdapter get( Object config ) throws ConfigurationException {
+    if( config == null ) {
+      throw new NullPointerException( "Configuration adapter instantiation impossible for null config object." );
+    }
+    try {
+      Map<Class<?>, Class<? extends ConfigurationAdapter>> adapters = getAdapters();
+      Class configType = config.getClass();
+      Class adapterType = findAdapterTypeForConfigTypeOrParent( adapters, configType );
+      if( adapterType == null ) {
+        throw new ConfigurationException( "No configuration adapter found for config type " + configType.getName() );
+      }
+      Constructor c = findConstructorForConfigType( adapterType, configType );
+      if( !c.isAccessible() ) {
+        c.setAccessible( true );
+      }
+      Object adapter = c.newInstance( config );
+      return ConfigurationAdapter.class.cast( adapter );
+    } catch( ConfigurationException e ) {
+      throw e;
+    } catch( Exception e ) {
+      throw new ConfigurationException( "Configuration adapter instantiation failed.", e );
+    }
+  }
+
+  public static Constructor findConstructorForConfigType( Class<?> adapterType, Class<?> configType ) throws NoSuchMethodException {
+    Constructor constructor = null;
+    Constructor[] constructors = adapterType.getConstructors();
+    for( Constructor candidate : constructors ) {
+      Class<?>[] paramTypes = candidate.getParameterTypes();
+      if( paramTypes.length == 1 ) {
+        Class<?> paramType = paramTypes[0];
+        if( paramType.isAssignableFrom( configType ) ) {
+          constructor = candidate;
+          break;
+        }
+      }
+    }
+    if( constructor == null ) {
+      throw new NoSuchMethodException( "No constructor for " + adapterType.getName() + " that will accept " + configType.getName() );
+    }
+    return constructor;
+  }
+
+  public static Class<? extends ConfigurationAdapter> findAdapterTypeForConfigTypeOrParent(
+      Map<Class<?>, Class<? extends ConfigurationAdapter>> adapters, Class<?> configType ) {
+    Class<? extends ConfigurationAdapter> adapterType = null;
+    while( configType != null ) {
+      adapterType = findAdapterTypeForConfigType( adapters, configType );
+      if( adapterType != null ) {
+        break;
+      }
+      configType = configType.getSuperclass();
+    }
+    return adapterType;
+  }
+
+  public static Class<? extends ConfigurationAdapter> findAdapterTypeForConfigType(
+      Map<Class<?>, Class<? extends ConfigurationAdapter>> adapters, Class<?> configType ) {
+    Class<? extends ConfigurationAdapter> adapterType = adapters.get( configType );
+    if( adapterType == null ) {
+      for( Class interfaceType : configType.getInterfaces() ) {
+        adapterType = findAdapterTypeForConfigTypeOrParent( adapters, interfaceType );
+        if( adapterType != null ) {
+          break;
+        }
+      }
+    }
+    return adapterType;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/DefaultConfigurationBinding.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/DefaultConfigurationBinding.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/DefaultConfigurationBinding.java
new file mode 100755
index 0000000..5629bc1
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/DefaultConfigurationBinding.java
@@ -0,0 +1,29 @@
+/**
+ * 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.config.impl;
+
+import org.apache.hadoop.gateway.config.ConfigurationBinding;
+
+public class DefaultConfigurationBinding implements ConfigurationBinding {
+
+  @Override
+  public String getConfigurationName( String name ) {
+    return name;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/DefaultConfigurationInjector.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/DefaultConfigurationInjector.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/DefaultConfigurationInjector.java
new file mode 100755
index 0000000..8b86ba1
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/DefaultConfigurationInjector.java
@@ -0,0 +1,224 @@
+/**
+ * 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.config.impl;
+
+import org.apache.commons.beanutils.ConvertUtilsBean2;
+import org.apache.hadoop.gateway.config.*;
+import org.apache.hadoop.gateway.config.spi.ConfigurationInjector;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+public class DefaultConfigurationInjector implements ConfigurationInjector {
+
+  private static ConvertUtilsBean2 DEFAULT_CONVERTER = new ConvertUtilsBean2();
+
+  @Override
+  public void configure( Object target, ConfigurationAdapter adapter, ConfigurationBinding binding )
+      throws ConfigurationException {
+    Class type = target.getClass();
+    while( type != null ) {
+      injectClass( type, target, adapter, binding );
+      type = type.getSuperclass();
+    }
+  }
+
+  private void injectClass( Class type, Object target, ConfigurationAdapter config, ConfigurationBinding binding )
+      throws ConfigurationException {
+    Field[] fields = type.getDeclaredFields();
+    for( Field field : fields ) {
+      injectFieldValue( field, target, config, binding );
+    }
+    Method[] methods = type.getDeclaredMethods();
+    for( Method method : methods ) {
+      injectMethodValue( method, target, config, binding );
+    }
+  }
+
+  private void injectFieldValue( Field field, Object target, ConfigurationAdapter adapter, ConfigurationBinding binding )
+      throws ConfigurationException {
+    Configure annotation = field.getAnnotation( Configure.class );
+    if( annotation != null ) {
+      Alias alias = field.getAnnotation( Alias.class );
+      String name = getConfigName( field, alias );
+      String bind = getBindName( target, name, binding );
+      Object value = retrieveValue( target, bind, name, field.getType(), adapter, binding );
+      if( value == null ) {
+        Optional optional = field.getAnnotation( Optional.class );
+        if( optional == null ) {
+          throw new ConfigurationException( String.format(
+              "Failed to find configuration for %s bound to %s of %s via %s",
+              bind, name, target.getClass().getName(), adapter.getClass().getName() ) );
+        }
+      } else {
+        try {
+          if( !field.isAccessible() ) {
+            field.setAccessible( true );
+          }
+          field.set( target, value );
+        } catch( Exception e ) {
+          throw new ConfigurationException( String.format(
+              "Failed to inject field configuration property %s of %s",
+              name, target.getClass().getName() ), e );
+        }
+      }
+    }
+  }
+
+  private void injectMethodValue( Method method, Object target, ConfigurationAdapter adapter, ConfigurationBinding binding )
+      throws ConfigurationException {
+    Configure methodTag = method.getAnnotation( Configure.class );
+    if( methodTag != null ) {
+      Alias aliasTag = method.getAnnotation( Alias.class );
+      String methodName = getConfigName( method, aliasTag );
+      Class[] argTypes = method.getParameterTypes();
+      Object[] args = new Object[ argTypes.length ];
+      Annotation[][] argTags = method.getParameterAnnotations();
+      for( int i=0; i<argTypes.length; i++ ) {
+        String argName = getConfigName( methodName, argTags[i] );
+        String bndName = getBindName( target, argName, binding );
+        Object argValue = retrieveValue( target, bndName, argName, argTypes[i], adapter, binding );
+        if( argValue == null ) {
+          Default defTag = findAnnotation( argTags[i], Default.class );
+          if( defTag != null ) {
+            String strValue = defTag.value();
+            argValue = convertValue( target, argName, strValue, argTypes[i] );
+          } else {
+            throw new ConfigurationException( String.format(
+                "Failed to find configuration for %s of %s via %s",
+                bndName, argName, target.getClass().getName(), adapter.getClass().getName() ) );
+          }
+        }
+        args[ i ] = argValue;
+      }
+      if( !method.isAccessible() ) {
+        method.setAccessible( true );
+      }
+      try {
+        method.invoke( target, args );
+      } catch( Exception e ) {
+        throw new ConfigurationException( String.format(
+            "Failed to inject method configuration via %s of %s",
+            methodName, target.getClass().getName() ), e );
+      }
+    }
+  }
+
+  private Object convertValue( Object target, String name, Object strValue, Class<?> type ) {
+    Object objValue = null;
+    try {
+      objValue = DEFAULT_CONVERTER.convert( strValue, type );
+    } catch( Exception e ) {
+      throw new ConfigurationException( String.format(
+          "Failed to convert configuration for %s of %s to %s",
+          name, target.getClass().getName(), type.getName() ), e );
+    }
+    return objValue;
+  }
+
+  private Object retrieveValue( Object target, String bind, String name, Class<?> type, ConfigurationAdapter adapter, ConfigurationBinding binding ) {
+    Object value;
+    try {
+      value = adapter.getConfigurationValue( bind );
+    } catch( Exception e ) {
+      throw new ConfigurationException( String.format(
+          "Failed to retrieve configuration for %s bound to %s of %s via %s",
+          bind, name, target.getClass().getName(), adapter.getClass().getName() ), e );
+    }
+    value = convertValue( target, name, value, type );
+    return value;
+  }
+
+  private <T extends Annotation> T findAnnotation( Annotation[] annotations, Class<T> type ) {
+    T found = null;
+    for( Annotation current : annotations ) {
+      if( type.isAssignableFrom( current.getClass() ) ) {
+        found = (T)current;
+        break;
+      }
+    }
+    return found;
+  }
+
+  private static String pickName( String implied, Alias explicit ) {
+    String name = implied;
+    if( explicit != null ) {
+      String tagValue = explicit.value().trim();
+      if( tagValue.length() > 0 ) {
+        name = tagValue;
+      }
+    }
+    return name;
+  }
+
+  private static String getBindName( Object target, String name, ConfigurationBinding binding ) {
+    String bind = null;
+    try {
+      bind = binding.getConfigurationName( name );
+    } catch( Exception e ) {
+      throw new ConfigurationException( String.format(
+          "Failed to bind configuration for %s of %s via %s",
+          name, target.getClass().getName(), binding.getClass().getName() ), e );
+    }
+    if( bind == null ) {
+      bind = name;
+    }
+    return bind;
+  }
+
+  private static String getConfigName( Field field, Alias tag ) {
+    return pickName( field.getName(), tag );
+  }
+
+  private static String getConfigName( String name, Annotation[] tags ) {
+    if( tags != null ) {
+      for( Annotation tag : tags ) {
+        if( tag != null && tag instanceof Alias ) {
+          Alias aliasTag = Alias.class.cast( tag );
+          String aliasValue = aliasTag.value().trim();
+          if( aliasValue.length() > 0 ) {
+            name = aliasValue;
+            break;
+          }
+        }
+      }
+    }
+    return name;
+  }
+
+  private static String getConfigName( Method method, Alias tag ) {
+    return pickName( getConfigName( method ), tag );
+  }
+
+  private static String getConfigName( Method method ) {
+    String methodName = method.getName();
+    StringBuilder name = new StringBuilder( methodName.length() );
+    if( methodName != null &&
+        methodName.length() > 3 &&
+        methodName.startsWith( "set" ) &&
+        Character.isUpperCase( methodName.charAt( 3 ) ) ) {
+      name.append( methodName.substring( 3 ) );
+      name.setCharAt( 0, Character.toLowerCase( name.charAt( 0 ) ) );
+    } else {
+      name.append( name );
+    }
+    return name.toString();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/MapConfigurationAdapter.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/MapConfigurationAdapter.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/MapConfigurationAdapter.java
new file mode 100755
index 0000000..d0556f4
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/MapConfigurationAdapter.java
@@ -0,0 +1,37 @@
+/**
+ * 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.config.impl;
+
+import org.apache.hadoop.gateway.config.ConfigurationAdapter;
+
+import java.util.Map;
+
+public class MapConfigurationAdapter implements ConfigurationAdapter {
+
+  private Map config;
+
+  public MapConfigurationAdapter( Map map ) {
+    this.config = map;
+  }
+
+  @Override
+  public Object getConfigurationValue( String name ) {
+    return config.get( name );
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/MapConfigurationAdapterDescriptor.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/MapConfigurationAdapterDescriptor.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/MapConfigurationAdapterDescriptor.java
new file mode 100755
index 0000000..4099483
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/MapConfigurationAdapterDescriptor.java
@@ -0,0 +1,30 @@
+/**
+ * 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.config.impl;
+
+import org.apache.hadoop.gateway.config.spi.AbstractConfigurationAdapterDescriptor;
+
+import java.util.Map;
+
+public class MapConfigurationAdapterDescriptor extends AbstractConfigurationAdapterDescriptor {
+
+  public MapConfigurationAdapterDescriptor() {
+    add( Map.class, MapConfigurationAdapter.class );
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/knox/blob/ea28bf22/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/MappedConfigurationBinding.java
----------------------------------------------------------------------
diff --git a/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/MappedConfigurationBinding.java b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/MappedConfigurationBinding.java
new file mode 100755
index 0000000..161869f
--- /dev/null
+++ b/gateway-util-configinjector/src/main/java/org/apache/hadoop/gateway/config/impl/MappedConfigurationBinding.java
@@ -0,0 +1,38 @@
+/**
+ * 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.config.impl;
+
+import org.apache.hadoop.gateway.config.ConfigurationBinding;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class MappedConfigurationBinding implements ConfigurationBinding {
+
+  private Map<String,String> map = new ConcurrentHashMap<String, String>();
+
+  public void bind( String targetName, String sourceName ) {
+    map.put( targetName, sourceName );
+  }
+
+  @Override
+  public String getConfigurationName( String name ) {
+    return map.get( name );
+  }
+
+}


Mime
View raw message