http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSJSONWriter.java
----------------------------------------------------------------------
diff --git 
a/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSJSONWriter.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSJSONWriter.java
new file mode 100644
index 0000000..3674e7a
--- /dev/null
+++ 
b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSJSONWriter.java
@@ -0,0 +1,70 @@
+/**
+ * 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.crypto.key.kms.server;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.codehaus.jackson.map.ObjectMapper;
+
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Jersey provider that converts <code>Map</code>s and <code>List</code>s
+ * to their JSON representation.
+ */
+@Provider
+@Produces(MediaType.APPLICATION_JSON)
[email protected]
+public class KMSJSONWriter implements MessageBodyWriter<Object> {
+
+  @Override
+  public boolean isWriteable(Class<?> aClass, Type type,
+      Annotation[] annotations, MediaType mediaType) {
+    return Map.class.isAssignableFrom(aClass) ||
+        List.class.isAssignableFrom(aClass);
+  }
+
+  @Override
+  public long getSize(Object obj, Class<?> aClass, Type type,
+      Annotation[] annotations, MediaType mediaType) {
+    return -1;
+  }
+
+  @Override
+  public void writeTo(Object obj, Class<?> aClass, Type type,
+      Annotation[] annotations, MediaType mediaType,
+      MultivaluedMap<String, Object> stringObjectMultivaluedMap,
+      OutputStream outputStream) throws IOException, WebApplicationException {
+    Writer writer = new OutputStreamWriter(outputStream);
+    ObjectMapper jsonMapper = new ObjectMapper();
+    jsonMapper.writerWithDefaultPrettyPrinter().writeValue(writer, obj);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSMDCFilter.java
----------------------------------------------------------------------
diff --git 
a/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSMDCFilter.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSMDCFilter.java
new file mode 100644
index 0000000..2a3c149
--- /dev/null
+++ 
b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSMDCFilter.java
@@ -0,0 +1,93 @@
+/**
+ * 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.crypto.key.kms.server;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.security.UserGroupInformation;
+import 
org.apache.hadoop.security.token.delegation.web.HttpUserGroupInformation;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+/**
+ * Servlet filter that captures context of the HTTP request to be use in the
+ * scope of KMS calls on the server side.
+ */
[email protected]
+public class KMSMDCFilter implements Filter {
+
+  private static class Data {
+    private UserGroupInformation ugi;
+    private String method;
+    private StringBuffer url;
+
+    private Data(UserGroupInformation ugi, String method, StringBuffer url) {
+      this.ugi = ugi;
+      this.method = method;
+      this.url = url;
+    }
+  }
+
+  private static ThreadLocal<Data> DATA_TL = new ThreadLocal<Data>();
+
+  public static UserGroupInformation getUgi() {
+    return DATA_TL.get().ugi;
+  }
+
+  public static String getMethod() {
+    return DATA_TL.get().method;
+  }
+
+  public static String getURL() {
+    return DATA_TL.get().url.toString();
+  }
+
+  @Override
+  public void init(FilterConfig config) throws ServletException {
+  }
+
+  @Override
+  public void doFilter(ServletRequest request, ServletResponse response,
+      FilterChain chain)
+      throws IOException, ServletException {
+    try {
+      DATA_TL.remove();
+      UserGroupInformation ugi = HttpUserGroupInformation.get();
+      String method = ((HttpServletRequest) request).getMethod();
+      StringBuffer requestURL = ((HttpServletRequest) request).getRequestURL();
+      String queryString = ((HttpServletRequest) request).getQueryString();
+      if (queryString != null) {
+        requestURL.append("?").append(queryString);
+      }
+      DATA_TL.set(new Data(ugi, method, requestURL));
+      chain.doFilter(request, response);
+    } finally {
+      DATA_TL.remove();
+    }
+  }
+
+  @Override
+  public void destroy() {
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSServerJSONUtils.java
----------------------------------------------------------------------
diff --git 
a/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSServerJSONUtils.java
 
b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSServerJSONUtils.java
new file mode 100644
index 0000000..24af81b
--- /dev/null
+++ 
b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSServerJSONUtils.java
@@ -0,0 +1,102 @@
+/**
+ * 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.crypto.key.kms.server;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.crypto.key.KeyProvider;
+import 
org.apache.hadoop.crypto.key.KeyProviderCryptoExtension.EncryptedKeyVersion;
+import org.apache.hadoop.crypto.key.kms.KMSRESTConstants;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * JSON utility methods for the KMS.
+ */
[email protected]
+public class KMSServerJSONUtils {
+  @SuppressWarnings("unchecked")
+  public static Map toJSON(KeyProvider.KeyVersion keyVersion) {
+    Map json = new LinkedHashMap();
+    if (keyVersion != null) {
+      json.put(KMSRESTConstants.NAME_FIELD,
+          keyVersion.getName());
+      json.put(KMSRESTConstants.VERSION_NAME_FIELD,
+          keyVersion.getVersionName());
+      json.put(KMSRESTConstants.MATERIAL_FIELD,
+          Base64.encodeBase64URLSafeString(
+              keyVersion.getMaterial()));
+    }
+    return json;
+  }
+
+  @SuppressWarnings("unchecked")
+  public static List toJSON(List<KeyProvider.KeyVersion> keyVersions) {
+    List json = new ArrayList();
+    if (keyVersions != null) {
+      for (KeyProvider.KeyVersion version : keyVersions) {
+        json.add(toJSON(version));
+      }
+    }
+    return json;
+  }
+
+  @SuppressWarnings("unchecked")
+  public static Map toJSON(EncryptedKeyVersion encryptedKeyVersion) {
+    Map json = new LinkedHashMap();
+    if (encryptedKeyVersion != null) {
+      json.put(KMSRESTConstants.VERSION_NAME_FIELD,
+          encryptedKeyVersion.getEncryptionKeyVersionName());
+      json.put(KMSRESTConstants.IV_FIELD,
+          Base64.encodeBase64URLSafeString(
+              encryptedKeyVersion.getEncryptedKeyIv()));
+      json.put(KMSRESTConstants.ENCRYPTED_KEY_VERSION_FIELD,
+          toJSON(encryptedKeyVersion.getEncryptedKeyVersion()));
+    }
+    return json;
+  }
+
+  @SuppressWarnings("unchecked")
+  public static Map toJSON(String keyName, KeyProvider.Metadata meta) {
+    Map json = new LinkedHashMap();
+    if (meta != null) {
+      json.put(KMSRESTConstants.NAME_FIELD, keyName);
+      json.put(KMSRESTConstants.CIPHER_FIELD, meta.getCipher());
+      json.put(KMSRESTConstants.LENGTH_FIELD, meta.getBitLength());
+      json.put(KMSRESTConstants.DESCRIPTION_FIELD, meta.getDescription());
+      json.put(KMSRESTConstants.ATTRIBUTES_FIELD, meta.getAttributes());
+      json.put(KMSRESTConstants.CREATED_FIELD,
+          meta.getCreated().getTime());
+      json.put(KMSRESTConstants.VERSIONS_FIELD,
+          (long) meta.getVersions());
+    }
+    return json;
+  }
+
+  @SuppressWarnings("unchecked")
+  public static List toJSON(String[] keyNames, KeyProvider.Metadata[] metas) {
+    List json = new ArrayList();
+    for (int i = 0; i < keyNames.length; i++) {
+      json.add(toJSON(keyNames[i], metas[i]));
+    }
+    return json;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSWebApp.java
----------------------------------------------------------------------
diff --git 
a/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSWebApp.java 
b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSWebApp.java
new file mode 100644
index 0000000..67b9f88
--- /dev/null
+++ b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KMSWebApp.java
@@ -0,0 +1,307 @@
+/**
+ * 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.crypto.key.kms.server;
+
+import com.codahale.metrics.JmxReporter;
+import com.codahale.metrics.Meter;
+import com.codahale.metrics.MetricRegistry;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.crypto.key.CachingKeyProvider;
+import org.apache.hadoop.crypto.key.KeyProvider;
+import org.apache.hadoop.crypto.key.KeyProviderCryptoExtension;
+import org.apache.hadoop.crypto.key.KeyProviderFactory;
+import 
org.apache.hadoop.crypto.key.kms.server.KeyAuthorizationKeyProvider.KeyACLs;
+import org.apache.hadoop.http.HttpServer2;
+import org.apache.hadoop.security.authorize.AccessControlList;
+import org.apache.hadoop.util.ReflectionUtils;
+import org.apache.hadoop.util.VersionInfo;
+import org.apache.log4j.PropertyConfigurator;
+import org.mortbay.log.Log;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.bridge.SLF4JBridgeHandler;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+
[email protected]
+public class KMSWebApp implements ServletContextListener {
+
+  private static final String LOG4J_PROPERTIES = "kms-log4j.properties";
+
+  private static final String METRICS_PREFIX = "hadoop.kms.";
+  private static final String ADMIN_CALLS_METER = METRICS_PREFIX +
+      "admin.calls.meter";
+  private static final String KEY_CALLS_METER = METRICS_PREFIX +
+      "key.calls.meter";
+  private static final String INVALID_CALLS_METER = METRICS_PREFIX +
+      "invalid.calls.meter";
+  private static final String UNAUTHORIZED_CALLS_METER = METRICS_PREFIX +
+      "unauthorized.calls.meter";
+  private static final String UNAUTHENTICATED_CALLS_METER = METRICS_PREFIX +
+      "unauthenticated.calls.meter";
+  private static final String GENERATE_EEK_METER = METRICS_PREFIX +
+      "generate_eek.calls.meter";
+  private static final String DECRYPT_EEK_METER = METRICS_PREFIX +
+      "decrypt_eek.calls.meter";
+
+  private static Logger LOG;
+  private static MetricRegistry metricRegistry;
+
+  private JmxReporter jmxReporter;
+  private static Configuration kmsConf;
+  private static KeyACLs kmsAcls;
+  private static Meter adminCallsMeter;
+  private static Meter keyCallsMeter;
+  private static Meter unauthorizedCallsMeter;
+  private static Meter unauthenticatedCallsMeter;
+  private static Meter decryptEEKCallsMeter;
+  private static Meter generateEEKCallsMeter;
+  private static Meter invalidCallsMeter;
+  private static KMSAudit kmsAudit;
+  private static KeyProviderCryptoExtension keyProviderCryptoExtension;
+
+  static {
+    SLF4JBridgeHandler.removeHandlersForRootLogger();
+    SLF4JBridgeHandler.install();
+  }
+
+  private void initLogging(String confDir) {
+    if (System.getProperty("log4j.configuration") == null) {
+      System.setProperty("log4j.defaultInitOverride", "true");
+      boolean fromClasspath = true;
+      File log4jConf = new File(confDir, LOG4J_PROPERTIES).getAbsoluteFile();
+      if (log4jConf.exists()) {
+        PropertyConfigurator.configureAndWatch(log4jConf.getPath(), 1000);
+        fromClasspath = false;
+      } else {
+        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+        URL log4jUrl = cl.getResource(LOG4J_PROPERTIES);
+        if (log4jUrl != null) {
+          PropertyConfigurator.configure(log4jUrl);
+        }
+      }
+      LOG = LoggerFactory.getLogger(KMSWebApp.class);
+      LOG.debug("KMS log starting");
+      if (fromClasspath) {
+        LOG.warn("Log4j configuration file '{}' not found", LOG4J_PROPERTIES);
+        LOG.warn("Logging with INFO level to standard output");
+      }
+    } else {
+      LOG = LoggerFactory.getLogger(KMSWebApp.class);
+    }
+  }
+
+  @Override
+  public void contextInitialized(ServletContextEvent sce) {
+    try {
+      String confDir = System.getProperty(KMSConfiguration.KMS_CONFIG_DIR);
+      if (confDir == null) {
+        throw new RuntimeException("System property '" +
+            KMSConfiguration.KMS_CONFIG_DIR + "' not defined");
+      }
+      kmsConf = KMSConfiguration.getKMSConf();
+      initLogging(confDir);
+      
LOG.info("-------------------------------------------------------------");
+      LOG.info("  Java runtime version : {}", System.getProperty(
+          "java.runtime.version"));
+      LOG.info("  KMS Hadoop Version: " + VersionInfo.getVersion());
+      
LOG.info("-------------------------------------------------------------");
+
+      
+      kmsAcls = getAcls(kmsConf.get(KMSConfiguration.KMS_SECURITY_AUTHORIZER));
+                 
+      //kmsAcls = new KMSACLs();
+      kmsAcls.startACLReloader();
+
+      metricRegistry = new MetricRegistry();
+      jmxReporter = JmxReporter.forRegistry(metricRegistry).build();
+      jmxReporter.start();
+      generateEEKCallsMeter = metricRegistry.register(GENERATE_EEK_METER,
+          new Meter());
+      decryptEEKCallsMeter = metricRegistry.register(DECRYPT_EEK_METER,
+          new Meter());
+      adminCallsMeter = metricRegistry.register(ADMIN_CALLS_METER, new 
Meter());
+      keyCallsMeter = metricRegistry.register(KEY_CALLS_METER, new Meter());
+      invalidCallsMeter = metricRegistry.register(INVALID_CALLS_METER,
+          new Meter());
+      unauthorizedCallsMeter = 
metricRegistry.register(UNAUTHORIZED_CALLS_METER,
+          new Meter());
+      unauthenticatedCallsMeter = metricRegistry.register(
+          UNAUTHENTICATED_CALLS_METER, new Meter());
+
+      kmsAudit =
+          new KMSAudit(kmsConf.getLong(
+              KMSConfiguration.KMS_AUDIT_AGGREGATION_WINDOW,
+              KMSConfiguration.KMS_AUDIT_AGGREGATION_WINDOW_DEFAULT));
+
+      // this is required for the the JMXJsonServlet to work properly.
+      // the JMXJsonServlet is behind the authentication filter,
+      // thus the '*' ACL.
+      sce.getServletContext().setAttribute(HttpServer2.CONF_CONTEXT_ATTRIBUTE,
+          kmsConf);
+      sce.getServletContext().setAttribute(HttpServer2.ADMINS_ACL,
+          new AccessControlList(AccessControlList.WILDCARD_ACL_VALUE));
+
+      // intializing the KeyProvider
+      String providerString = kmsConf.get(KMSConfiguration.KEY_PROVIDER_URI);
+      if (providerString == null) {
+        throw new IllegalStateException("No KeyProvider has been defined");
+      }
+      Log.info("------------------ Ranger KMSWEbApp---------------------");
+      Log.info("provider string = "+providerString);
+      Log.info("URI = "+new URI(providerString).toString()+" scheme = "+new 
URI(providerString).getScheme());
+      Log.info("kmsconf size= "+kmsConf.size() + " kms 
classname="+kmsConf.getClass().getName());
+      Log.info("----------------INstantiating key provider ---------------");
+      KeyProvider keyProvider =
+          KeyProviderFactory.get(new URI(providerString), kmsConf);
+      Log.info("keyProvider = "+keyProvider.toString());
+      if (kmsConf.getBoolean(KMSConfiguration.KEY_CACHE_ENABLE,
+          KMSConfiguration.KEY_CACHE_ENABLE_DEFAULT)) {
+        long keyTimeOutMillis =
+            kmsConf.getLong(KMSConfiguration.KEY_CACHE_TIMEOUT_KEY,
+                KMSConfiguration.KEY_CACHE_TIMEOUT_DEFAULT);
+        long currKeyTimeOutMillis =
+            kmsConf.getLong(KMSConfiguration.CURR_KEY_CACHE_TIMEOUT_KEY,
+                KMSConfiguration.CURR_KEY_CACHE_TIMEOUT_DEFAULT);
+        keyProvider = new CachingKeyProvider(keyProvider, keyTimeOutMillis,
+            currKeyTimeOutMillis);
+      }
+      LOG.info("Initialized KeyProvider " + keyProvider);
+
+      keyProviderCryptoExtension = KeyProviderCryptoExtension.
+          createKeyProviderCryptoExtension(keyProvider);
+      keyProviderCryptoExtension =
+          new EagerKeyGeneratorKeyProviderCryptoExtension(kmsConf,
+              keyProviderCryptoExtension);
+      if (kmsConf.getBoolean(KMSConfiguration.KEY_AUTHORIZATION_ENABLE,
+          KMSConfiguration.KEY_AUTHORIZATION_ENABLE_DEFAULT)) {
+        keyProviderCryptoExtension =
+            new KeyAuthorizationKeyProvider(
+                keyProviderCryptoExtension, kmsAcls);
+      }
+        
+      LOG.info("Initialized KeyProviderCryptoExtension "
+          + keyProviderCryptoExtension);
+      final int defaultBitlength = kmsConf
+          .getInt(KeyProvider.DEFAULT_BITLENGTH_NAME,
+              KeyProvider.DEFAULT_BITLENGTH);
+      LOG.info("Default key bitlength is {}", defaultBitlength);
+      LOG.info("Ranger KMS Started");
+    } catch (Throwable ex) {
+      System.out.println();
+      System.out.println("ERROR: Hadoop KMS could not be started");
+      System.out.println();
+      System.out.println("REASON: " + ex.toString());
+      System.out.println();
+      System.out.println("Stacktrace:");
+      
System.out.println("---------------------------------------------------");
+      ex.printStackTrace(System.out);
+      
System.out.println("---------------------------------------------------");
+      System.out.println();
+      System.exit(1);
+    }
+  }
+
+  private KeyACLs getAcls(String clsStr) throws IOException {
+         KeyACLs keyAcl = null;
+         try {
+        Class<? extends KeyACLs> cls = null;
+        if (clsStr == null || clsStr.trim().equals("")) {
+               cls = KMSACLs.class;
+        } else {
+            //Class<?> configClass = Class.forName(clsStr, true, 
JavaUtils.getClassLoader());
+               Class<?> configClass = Class.forName(clsStr);
+            //Class<?> configClass = Class.forName(clsStr, true, 
JavaUtils.getClassLoader());
+            if(!KeyACLs.class.isAssignableFrom(configClass) ){
+               //if it's not of type KeyACLs
+               //we can have default also "cls = KMSACLs.class;"
+                   return null;
+            }
+            cls = (Class<? extends KeyACLs>)configClass;
+        }
+        if (cls != null) {
+            keyAcl = ReflectionUtils.newInstance(cls, kmsConf);
+        }
+      } catch (Exception e) {
+               throw new IOException(e.getMessage());
+      }
+         return keyAcl;
+  }
+
+@Override
+  public void contextDestroyed(ServletContextEvent sce) {
+    kmsAudit.shutdown();
+    kmsAcls.stopACLReloader();
+    jmxReporter.stop();
+    jmxReporter.close();
+    metricRegistry = null;
+    LOG.info("KMS Stopped");
+  }
+
+  public static Configuration getConfiguration() {
+    return new Configuration(kmsConf);
+  }
+
+  public static KeyACLs getACLs() {
+    return kmsAcls;
+  }
+
+  public static Meter getAdminCallsMeter() {
+    return adminCallsMeter;
+  }
+
+  public static Meter getKeyCallsMeter() {
+    return keyCallsMeter;
+  }
+
+  public static Meter getInvalidCallsMeter() {
+    return invalidCallsMeter;
+  }
+
+  public static Meter getGenerateEEKCallsMeter() {
+    return generateEEKCallsMeter;
+  }
+
+  public static Meter getDecryptEEKCallsMeter() {
+    return decryptEEKCallsMeter;
+  }
+
+  public static Meter getUnauthorizedCallsMeter() {
+    return unauthorizedCallsMeter;
+  }
+
+  public static Meter getUnauthenticatedCallsMeter() {
+    return unauthenticatedCallsMeter;
+  }
+
+  public static KeyProviderCryptoExtension getKeyProvider() {
+    return keyProviderCryptoExtension;
+  }
+
+  public static KMSAudit getKMSAudit() {
+    return kmsAudit;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KeyAuthorizationKeyProvider.java
----------------------------------------------------------------------
diff --git 
a/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KeyAuthorizationKeyProvider.java
 
b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KeyAuthorizationKeyProvider.java
new file mode 100644
index 0000000..5099daf
--- /dev/null
+++ 
b/kms/src/main/java/org/apache/hadoop/crypto/key/kms/server/KeyAuthorizationKeyProvider.java
@@ -0,0 +1,299 @@
+/**
+ * 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.crypto.key.kms.server;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.hadoop.crypto.key.KeyProvider;
+import org.apache.hadoop.crypto.key.KeyProviderCryptoExtension;
+import org.apache.hadoop.crypto.key.kms.server.KMS.KMSOp;
+import org.apache.hadoop.security.AccessControlException;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.authorize.AuthorizationException;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * A {@link KeyProvider} proxy that checks whether the current user derived via
+ * {@link UserGroupInformation}, is authorized to perform the following
+ * type of operations on a Key :
+ * <ol>
+ * <li>MANAGEMENT operations : createKey, rollNewVersion, deleteKey</li>
+ * <li>GENERATE_EEK operations : generateEncryptedKey, warmUpEncryptedKeys</li>
+ * <li>DECRYPT_EEK operation : decryptEncryptedKey</li>
+ * <li>READ operations : getKeyVersion, getKeyVersions, getMetadata,
+ * getKeysMetadata, getCurrentKey</li>
+ * </ol>
+ * The read operations (getCurrentKeyVersion / getMetadata) etc are not 
checked.
+ */
+public class KeyAuthorizationKeyProvider extends KeyProviderCryptoExtension {
+
+  public static final String KEY_ACL = "key.acl.";
+  private static final String KEY_ACL_NAME = KEY_ACL + "name";
+
+  public enum KeyOpType {
+    ALL, READ, MANAGEMENT, GENERATE_EEK, DECRYPT_EEK;
+  }
+
+  /**
+   * Interface that needs to be implemented by a client of the
+   * <code>KeyAuthorizationKeyProvider</code>.
+   */
+  public static interface KeyACLs {
+    
+    /**
+     * This is called by the KeyProvider to check if the given user is
+     * authorized to perform the specified operation on the given acl name.
+     * @param aclName name of the key ACL
+     * @param ugi User's UserGroupInformation
+     * @param opType Operation Type 
+     * @return true if user has access to the aclName and opType else false
+     */
+    public boolean hasAccessToKey(String aclName, UserGroupInformation ugi,
+        KeyOpType opType);
+
+    /**
+     * 
+     * @param aclName ACL name
+     * @param opType Operation Type
+     * @return true if AclName exists else false 
+     */
+    public boolean isACLPresent(String aclName, KeyOpType opType);
+
+       public void startACLReloader();
+       
+       public void stopACLReloader();
+
+       public boolean hasAccess(KMSACLsType.Type aclType, UserGroupInformation 
ugi);
+
+       public void assertAccess(KMSACLsType.Type aclType, UserGroupInformation 
ugi,
+                       KMSOp operation, String key) throws 
AccessControlException;
+  }
+
+  private final KeyProviderCryptoExtension provider;
+  private final KeyACLs acls;
+
+  /**
+   * The constructor takes a {@link KeyProviderCryptoExtension} and an
+   * implementation of <code>KeyACLs</code>. All calls are delegated to the
+   * provider keyProvider after authorization check (if required)
+   * @param keyProvider 
+   * @param acls
+   */
+  public KeyAuthorizationKeyProvider(KeyProviderCryptoExtension keyProvider,
+      KeyACLs acls) {
+    super(keyProvider, null);
+    this.provider = keyProvider;
+    this.acls = acls;
+  }
+
+  // This method first checks if "key.acl.name" attribute is present as an
+  // attribute in the provider Options. If yes, use the aclName for any
+  // subsequent access checks, else use the keyName as the aclName and set it
+  // as the value of the "key.acl.name" in the key's metadata.
+  private void authorizeCreateKey(String keyName, Options options,
+      UserGroupInformation ugi) throws IOException{
+    Preconditions.checkNotNull(ugi, "UserGroupInformation cannot be null");
+    Map<String, String> attributes = options.getAttributes();
+    String aclName = attributes.get(KEY_ACL_NAME);
+    boolean success = false;
+    if (Strings.isNullOrEmpty(aclName)) {
+      if (acls.isACLPresent(keyName, KeyOpType.MANAGEMENT)) {
+        options.setAttributes(ImmutableMap.<String, String> builder()
+            .putAll(attributes).put(KEY_ACL_NAME, keyName).build());
+        success =
+            acls.hasAccessToKey(keyName, ugi, KeyOpType.MANAGEMENT)
+                || acls.hasAccessToKey(keyName, ugi, KeyOpType.ALL);
+      } else {
+        success = false;
+      }
+    } else {
+      success = acls.isACLPresent(aclName, KeyOpType.MANAGEMENT) &&
+          (acls.hasAccessToKey(aclName, ugi, KeyOpType.MANAGEMENT)
+          || acls.hasAccessToKey(aclName, ugi, KeyOpType.ALL));
+    }
+    if (!success)
+      throw new AuthorizationException(String.format("User [%s] is not"
+          + " authorized to create key !!", ugi.getShortUserName()));
+  }
+
+  private void checkAccess(String aclName, UserGroupInformation ugi,
+      KeyOpType opType) throws AuthorizationException {
+    Preconditions.checkNotNull(aclName, "Key ACL name cannot be null");
+    Preconditions.checkNotNull(ugi, "UserGroupInformation cannot be null");
+    if (acls.isACLPresent(aclName, KeyOpType.MANAGEMENT) &&
+        (acls.hasAccessToKey(aclName, ugi, opType)
+            || acls.hasAccessToKey(aclName, ugi, KeyOpType.ALL))) {
+      return;
+    } else {
+      throw new AuthorizationException(String.format("User [%s] is not"
+          + " authorized to perform [%s] on key with ACL name [%s]!!",
+          ugi.getShortUserName(), opType, aclName));
+    }
+  }
+
+  @Override
+  public KeyVersion createKey(String name, Options options)
+      throws NoSuchAlgorithmException, IOException {
+    authorizeCreateKey(name, options, getUser());
+    return provider.createKey(name, options);
+  }
+
+  @Override
+  public KeyVersion createKey(String name, byte[] material, Options options)
+      throws IOException {
+    authorizeCreateKey(name, options, getUser());
+    return provider.createKey(name, material, options);
+  }
+
+  @Override
+  public KeyVersion rollNewVersion(String name)
+      throws NoSuchAlgorithmException, IOException {
+    doAccessCheck(name, KeyOpType.MANAGEMENT);
+    return provider.rollNewVersion(name);
+  }
+
+  @Override
+  public void deleteKey(String name) throws IOException {
+    doAccessCheck(name, KeyOpType.MANAGEMENT);
+    provider.deleteKey(name);
+  }
+
+  @Override
+  public KeyVersion rollNewVersion(String name, byte[] material)
+      throws IOException {
+    doAccessCheck(name, KeyOpType.MANAGEMENT);
+    return provider.rollNewVersion(name, material);
+  }
+
+  @Override
+  public void warmUpEncryptedKeys(String... names) throws IOException {
+    for (String name : names) {
+      doAccessCheck(name, KeyOpType.GENERATE_EEK);
+    }
+    provider.warmUpEncryptedKeys(names);
+  }
+
+  @Override
+  public EncryptedKeyVersion generateEncryptedKey(String encryptionKeyName)
+      throws IOException, GeneralSecurityException {
+    doAccessCheck(encryptionKeyName, KeyOpType.GENERATE_EEK);
+    return provider.generateEncryptedKey(encryptionKeyName);
+  }
+
+  private void verifyKeyVersionBelongsToKey(EncryptedKeyVersion ekv)
+      throws IOException {
+    String kn = ekv.getEncryptionKeyName();
+    String kvn = ekv.getEncryptionKeyVersionName();
+    KeyVersion kv = provider.getKeyVersion(kvn);
+    if (!kv.getName().equals(kn)) {
+      throw new IllegalArgumentException(String.format(
+          "KeyVersion '%s' does not belong to the key '%s'", kvn, kn));
+    }
+  }
+
+  @Override
+  public KeyVersion decryptEncryptedKey(EncryptedKeyVersion 
encryptedKeyVersion)
+          throws IOException, GeneralSecurityException {
+    verifyKeyVersionBelongsToKey(encryptedKeyVersion);
+    doAccessCheck(
+        encryptedKeyVersion.getEncryptionKeyName(), KeyOpType.DECRYPT_EEK);
+    return provider.decryptEncryptedKey(encryptedKeyVersion);
+  }
+
+  @Override
+  public KeyVersion getKeyVersion(String versionName) throws IOException {
+    KeyVersion keyVersion = provider.getKeyVersion(versionName);
+    if (keyVersion != null) {
+      doAccessCheck(keyVersion.getName(), KeyOpType.READ);
+    }
+    return keyVersion;
+  }
+
+  @Override
+  public List<String> getKeys() throws IOException {
+    return provider.getKeys();
+  }
+
+  @Override
+  public List<KeyVersion> getKeyVersions(String name) throws IOException {
+    doAccessCheck(name, KeyOpType.READ);
+    return provider.getKeyVersions(name);
+  }
+
+  @Override
+  public Metadata getMetadata(String name) throws IOException {
+    doAccessCheck(name, KeyOpType.READ);
+    return provider.getMetadata(name);
+  }
+
+  @Override
+  public Metadata[] getKeysMetadata(String... names) throws IOException {
+    for (String name : names) {
+      doAccessCheck(name, KeyOpType.READ);
+    }
+    return provider.getKeysMetadata(names);
+  }
+
+  @Override
+  public KeyVersion getCurrentKey(String name) throws IOException {
+    doAccessCheck(name, KeyOpType.READ);
+    return provider.getCurrentKey(name);
+  }
+
+  @Override
+  public void flush() throws IOException {
+    provider.flush();
+  }
+
+  @Override
+  public boolean isTransient() {
+    return provider.isTransient();
+  }
+
+  private void doAccessCheck(String keyName, KeyOpType opType) throws
+      IOException {
+    Metadata metadata = provider.getMetadata(keyName);
+    if (metadata != null) {
+      String aclName = metadata.getAttributes().get(KEY_ACL_NAME);
+      checkAccess((aclName == null) ? keyName : aclName, getUser(), opType);
+    }
+  }
+
+  private UserGroupInformation getUser() throws IOException {
+    return UserGroupInformation.getCurrentUser();
+  }
+
+  @Override
+  protected KeyProvider getKeyProvider() {
+    return this;
+  }
+
+  @Override
+  public String toString() {
+    return provider.toString();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/entity/XXDBBase.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/entity/XXDBBase.java 
b/kms/src/main/java/org/apache/ranger/entity/XXDBBase.java
new file mode 100644
index 0000000..08ab1f7
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/entity/XXDBBase.java
@@ -0,0 +1,216 @@
+package org.apache.ranger.entity;
+
+/**
+ * Base JPA class with id, versionNumber and other common attributes
+ * 
+ */
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+
+import javax.persistence.Column;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@MappedSuperclass
+@XmlRootElement
+public abstract class XXDBBase extends Object implements java.io.Serializable {
+       private static final long serialVersionUID = 1L;
+       public static final int CLASS_TYPE_NONE = 0;
+       private static final TimeZone gmtTimeZone = 
TimeZone.getTimeZone("GMT+0");
+       
+       /**
+        * Date/Time creation of this user.
+        * <ul>
+        * </ul>
+        *
+        */
+       @Temporal(TemporalType.TIMESTAMP)
+       @Column(name="CREATE_TIME"   )
+       protected Date createTime = getUTCDate();
+
+       /**
+        * Date value.
+        * <ul>
+        * </ul>
+        *
+        */
+       @Temporal(TemporalType.TIMESTAMP)
+       @Column(name="UPDATE_TIME"   )
+       protected Date updateTime = getUTCDate();
+
+       /**
+        * Added by
+        * <ul>
+        * </ul>
+        *
+        */
+       @Column(name="ADDED_BY_ID"   )
+       protected Long addedByUserId;
+
+
+       /**
+        * Last updated by
+        * <ul>
+        * </ul>
+        *
+        */
+       @Column(name="UPD_BY_ID"   )
+       protected Long updatedByUserId;
+
+
+       /**
+        * Default constructor. This will set all the attributes to default 
value.
+        */
+       public XXDBBase ( ) {
+       }
+
+       public int getMyClassType( ) {
+           return CLASS_TYPE_NONE;
+       }
+
+       public String getMyDisplayValue() {
+               return null;
+       }
+
+       /**
+        * This method sets the value to the member attribute <b>id</b>.
+        * You cannot set null to the attribute.
+        * @param id Value to set member attribute <b>id</b>
+        */
+       public abstract void setId( Long id ) ;
+
+       /**
+        * Returns the value for the member attribute <b>id</b>
+        * @return Long - value of member attribute <b>id</b>.
+        */
+       public abstract Long getId( );
+
+       /**
+        * This method sets the value to the member attribute <b>createTime</b>.
+        * You cannot set null to the attribute.
+        * @param createTime Value to set member attribute <b>createTime</b>
+        */
+       public void setCreateTime( Date createTime ) {
+               this.createTime = createTime;
+       }
+
+       /**
+        * Returns the value for the member attribute <b>createTime</b>
+        * @return Date - value of member attribute <b>createTime</b>.
+        */
+       public Date getCreateTime( ) {
+               return this.createTime;
+       }
+
+       /**
+        * This method sets the value to the member attribute <b>updateTime</b>.
+        * You cannot set null to the attribute.
+        * @param updateTime Value to set member attribute <b>updateTime</b>
+        */
+       public void setUpdateTime( Date updateTime ) {
+               this.updateTime = updateTime;
+       }
+
+       /**
+        * Returns the value for the member attribute <b>updateTime</b>
+        * @return Date - value of member attribute <b>updateTime</b>.
+        */
+       public Date getUpdateTime( ) {
+               return this.updateTime;
+       }
+
+       /**
+        * This method sets the value to the member attribute 
<b>addedByUserId</b>.
+        * You cannot set null to the attribute.
+        * @param addedByUserId Value to set member attribute 
<b>addedByUserId</b>
+        */
+       public void setAddedByUserId( Long addedByUserId ) {
+               this.addedByUserId = addedByUserId;
+       }
+
+       /**
+        * Returns the value for the member attribute <b>addedByUserId</b>
+        * @return Long - value of member attribute <b>addedByUserId</b>.
+        */
+       public Long getAddedByUserId( ) {
+               return this.addedByUserId;
+       }
+
+
+       /**
+        * This method sets the value to the member attribute 
<b>updatedByUserId</b>.
+        * You cannot set null to the attribute.
+        * @param updatedByUserId Value to set member attribute 
<b>updatedByUserId</b>
+        */
+       public void setUpdatedByUserId( Long updatedByUserId ) {
+               this.updatedByUserId = updatedByUserId;
+       }
+
+       /**
+        * Returns the value for the member attribute <b>updatedByUserId</b>
+        * @return Long - value of member attribute <b>updatedByUserId</b>.
+        */
+       public Long getUpdatedByUserId( ) {
+               return this.updatedByUserId;
+       }
+
+
+       /**
+        * This return the bean content in string format
+        * @return formatedStr
+       */
+       @Override
+       public String toString( ) {
+               String str = "XXDBBase={";
+               //`str += "id={" + id + "} ";
+               str += "createTime={" + createTime + "} ";
+               str += "updateTime={" + updateTime + "} ";
+               str += "addedByUserId={" + addedByUserId + "} ";
+               str += "updatedByUserId={" + updatedByUserId + "} ";
+               str += "}";
+               return str;
+       }
+
+       /**
+        * Checks for all attributes except referenced db objects
+        * @return true if all attributes match
+       */
+       @Override
+       public boolean equals( Object obj) {
+               XXDBBase other = (XXDBBase) obj;
+               if ((this.createTime == null && other.createTime != null) || 
(this.createTime != null && !this.createTime.equals(other.createTime))) {
+                       return false;
+               }
+               if ((this.updateTime == null && other.updateTime != null) || 
(this.updateTime != null && !this.updateTime.equals(other.updateTime))) {
+                       return false;
+               }
+               if ((this.addedByUserId == null && other.addedByUserId != null) 
|| (this.addedByUserId != null && 
!this.addedByUserId.equals(other.addedByUserId))) {
+                       return false;
+               }
+               if ((this.updatedByUserId == null && other.updatedByUserId != 
null) || (this.updatedByUserId != null && 
!this.updatedByUserId.equals(other.updatedByUserId))) {
+                       return false;
+               }
+               return true;
+       }
+       public static String getEnumName(String fieldName ) {
+               return null;
+       }
+
+       private static Date getUTCDate(){
+               try{
+                       Calendar local=Calendar.getInstance();
+                   int offset = 
local.getTimeZone().getOffset(local.getTimeInMillis());
+                   GregorianCalendar utc = new GregorianCalendar(gmtTimeZone);
+                   utc.setTimeInMillis(local.getTimeInMillis());
+                   utc.add(Calendar.MILLISECOND, -offset);
+                   return utc.getTime();
+               }catch(Exception ex){
+                       return null;
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/entity/XXRangerKeyStore.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/entity/XXRangerKeyStore.java 
b/kms/src/main/java/org/apache/ranger/entity/XXRangerKeyStore.java
new file mode 100644
index 0000000..c9eb77e
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/entity/XXRangerKeyStore.java
@@ -0,0 +1,121 @@
+package org.apache.ranger.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@Entity
+@Table(name="ranger_keystore")
+@XmlRootElement
+public class XXRangerKeyStore extends XXDBBase implements java.io.Serializable 
{
+       private static final long serialVersionUID = 1L;
+       
+       @Id
+       
@SequenceGenerator(name="kmskeys",sequenceName="kmskeys",allocationSize=1)
+       @GeneratedValue(strategy=GenerationType.AUTO,generator="kmskeys")
+       @Column(name="ID")
+       protected Long id;
+       @Override
+       public void setId(Long id) {
+               this.id=id;
+       }
+
+       @Override
+       public Long getId() {
+               return id;
+       }
+       
+       @Column(name="kms_alias"  , length=255 )
+       protected String alias;
+       
+       public String getAlias() {
+               return alias;
+       }
+
+       public void setAlias(String alias) {
+               this.alias = alias;
+       }
+       
+       @Column(name="kms_createdDate"  , length=255 )
+       protected Long createdDate;
+       
+       public Long getCreatedDate() {
+               return createdDate;
+       }
+
+       public void setCreatedDate(Long createdDate) {
+               this.createdDate = createdDate;
+       }
+
+       @Lob
+       @Column(name="kms_encoded")
+       protected String encoded;
+
+       public String getEncoded() {
+               return encoded;
+       }
+
+       public void setEncoded(String encoded) {
+               this.encoded = encoded;
+       }
+       
+       @Column(name="kms_cipher" , length=255)
+       protected String cipher;
+       
+       public String getCipher() {
+               return cipher;
+       }
+
+       public void setCipher(String cipher) {
+               this.cipher = cipher;
+       }
+
+       @Column(name="kms_bitLength")
+       protected int bitLength;
+       
+       public int getBitLength() {
+               return bitLength;
+       }
+
+       public void setBitLength(int bitLength) {
+               this.bitLength = bitLength;
+       }
+       
+       @Column(name="kms_description")
+       protected String description;
+       
+       public String getDescription() {
+               return description;
+       }
+
+       public void setDescription(String description) {
+               this.description = description;
+       }
+       
+       @Column(name="kms_version")
+       protected int version;
+       
+       public int getVersion() {
+               return version;
+       }
+
+       public void setVersion(int version) {
+               this.version = version;
+       }
+       
+       @Column(name="kms_attributes")
+       protected String attributes;
+       public String getAttributes() {
+               return attributes;
+       }
+
+       public void setAttributes(String attributes) {
+               this.attributes = attributes;
+       }       
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/entity/XXRangerMasterKey.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/entity/XXRangerMasterKey.java 
b/kms/src/main/java/org/apache/ranger/entity/XXRangerMasterKey.java
new file mode 100644
index 0000000..6175286
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/entity/XXRangerMasterKey.java
@@ -0,0 +1,67 @@
+package org.apache.ranger.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@Entity
+@Table(name="ranger_masterkey")
+@XmlRootElement
+public class XXRangerMasterKey extends XXDBBase implements 
java.io.Serializable {
+       private static final long serialVersionUID = 1L;
+       
+       @Id
+       
@SequenceGenerator(name="rangermasterkey",sequenceName="rangermasterkey",allocationSize=1)
+       
@GeneratedValue(strategy=GenerationType.AUTO,generator="rangermasterkey")
+       @Column(name="ID")
+       protected Long id;
+       @Override
+       public void setId(Long id) {
+               this.id=id;
+       }
+
+       @Override
+       public Long getId() {
+               return id;
+       }
+       
+       @Column(name="cipher")
+       protected String cipher;
+
+       public String getCipher() {
+               return cipher;
+       }
+
+       public void setCipher(String cipher) {
+               this.cipher = cipher;
+       }
+       
+       @Column(name="bitlength")
+       protected int bitLength;
+
+       public int getBitLength() {
+               return bitLength;
+       }
+
+       public void setBitLength(int bitLength) {
+               this.bitLength = bitLength;
+       }
+               
+       @Lob
+       @Column(name="masterkey")
+       protected String masterKey;
+
+       public String getMasterKey() {
+               return masterKey;
+       }
+
+       public void setMasterKey(String masterKey) {
+               this.masterKey = masterKey;
+       }               
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/kms/biz/RangerKMSStartUp.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/kms/biz/RangerKMSStartUp.java 
b/kms/src/main/java/org/apache/ranger/kms/biz/RangerKMSStartUp.java
new file mode 100644
index 0000000..af9bfa1
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/kms/biz/RangerKMSStartUp.java
@@ -0,0 +1,35 @@
+package org.apache.ranger.kms.biz;
+
+import javax.annotation.PostConstruct;
+import javax.servlet.http.HttpServlet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.crypto.key.RangerKeyStoreProvider;
+import org.apache.hadoop.crypto.key.RangerMasterKey;
+import org.springframework.stereotype.Component;
+
+@SuppressWarnings("serial")
+@Component
+public class RangerKMSStartUp extends HttpServlet
+{      
+       public static final String ENCRYPTION_KEY = 
"ranger.db.encrypt.key.password";
+       private static Logger LOG = 
LoggerFactory.getLogger(RangerKMSStartUp.class);
+       
+       @PostConstruct
+       public void initRangerMasterKey() {
+               LOG.info("Ranger KMSStartUp");
+               RangerMasterKey rangerMasterKey = new RangerMasterKey();
+               try {
+                               Configuration conf = 
RangerKeyStoreProvider.getDBKSConf();
+                               String password = conf.get(ENCRYPTION_KEY);
+                               boolean check = 
rangerMasterKey.generateMasterKey(password);
+                               if(check){
+                                       LOG.info("MasterKey Generated..");
+                               }
+               } catch (Throwable e) {
+                       e.printStackTrace();
+               }                               
+       }       
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/kms/dao/BaseDao.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/kms/dao/BaseDao.java 
b/kms/src/main/java/org/apache/ranger/kms/dao/BaseDao.java
new file mode 100644
index 0000000..f835bcc
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/kms/dao/BaseDao.java
@@ -0,0 +1,261 @@
+/*
+ * 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.ranger.kms.dao;
+
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+import javax.persistence.NoResultException;
+import javax.persistence.TypedQuery;
+
+import org.apache.log4j.Logger;
+
+public abstract class BaseDao<T> {
+       static final Logger logger = Logger.getLogger(BaseDao.class);
+
+       protected DaoManager daoManager;
+
+       protected Class<T> tClass;
+
+       public BaseDao(DaoManagerBase daoManager) {
+               this.init(daoManager);
+       }
+
+       @SuppressWarnings("unchecked")
+       private void init(DaoManagerBase daoManager) {
+               this.daoManager = (DaoManager) daoManager;
+
+               ParameterizedType genericSuperclass = (ParameterizedType) 
getClass()
+                               .getGenericSuperclass();
+
+               Type type = genericSuperclass.getActualTypeArguments()[0];
+
+               if (type instanceof ParameterizedType) {
+                       this.tClass = (Class<T>) ((ParameterizedType) 
type).getRawType();
+               } else {
+                       this.tClass = (Class<T>) type;
+               }
+       }
+
+       public EntityManager getEntityManager() {
+               return daoManager.getEntityManager();
+       }
+
+       public boolean beginTransaction() {
+               boolean ret = false;
+
+               EntityManager em = getEntityManager();
+
+               if(em != null) {
+                       EntityTransaction et = em.getTransaction();
+                       
+                       // check the transaction is not already active
+                       if(et != null && !et.isActive()) {
+                               et.begin();
+                               ret = true;
+                       }
+               }
+               
+               return ret;
+       }
+
+       public void commitTransaction() {
+               EntityManager em = getEntityManager();
+
+               if(em != null) {
+                       em.flush();
+
+                       EntityTransaction et = em.getTransaction();
+
+                       if(et != null) {
+                               et.commit();
+                       }
+               }
+       }
+
+       public void rollbackTransaction() {
+               EntityManager em = getEntityManager();
+
+               if(em != null) {
+                       EntityTransaction et = em.getTransaction();
+
+                       if(et != null) {
+                               et.rollback();
+                       }
+               }
+       }
+
+       public T create(T obj) {
+               T ret = null;
+
+               boolean trxBegan = beginTransaction();
+
+               getEntityManager().persist(obj);
+
+               if(trxBegan) {
+                       commitTransaction();
+               }
+
+               ret = obj;
+
+               return ret;
+       }
+
+       public T update(T obj) {
+               boolean trxBegan = beginTransaction();
+
+               getEntityManager().merge(obj);
+
+               if(trxBegan) {
+                       commitTransaction();
+               }
+
+               return obj;
+       }
+
+       public boolean remove(Long id) {
+               return remove(getById(id));
+       }
+
+       public boolean remove(T obj) {
+               if (obj == null) {
+                       return true;
+               }
+
+               boolean ret = false;
+
+               boolean trxBegan = beginTransaction();
+
+               getEntityManager().remove(obj);
+
+               if(trxBegan) {
+                       commitTransaction();
+               }
+
+               ret = true;
+
+               return ret;
+       }
+
+       public T getById(Long id) {
+               if (id == null) {
+                       return null;
+               }
+               T ret = null;
+               try {
+                       ret = getEntityManager().find(tClass, id);
+               } catch (NoResultException e) {
+                       return null;
+               }
+               return ret;
+       }
+
+       public List<T> getAll() {
+               List<T> ret = null;
+               
+               TypedQuery<T> qry = getEntityManager().createQuery(
+                               "SELECT t FROM " + tClass.getSimpleName() + " 
t", tClass);
+
+               ret = qry.getResultList();
+
+               return ret;
+       }
+
+       public Long getAllCount() {
+               Long ret = null;
+
+               TypedQuery<Long> qry = getEntityManager().createQuery(
+                               "SELECT count(t) FROM " + 
tClass.getSimpleName() + " t",
+                               Long.class);
+
+               ret = qry.getSingleResult();
+
+               return ret;
+       }
+
+       public T getUniqueResult(TypedQuery<T> qry) {
+               T ret = null;
+
+               try {
+                       ret = qry.getSingleResult();
+               } catch (NoResultException e) {
+                       // ignore
+               }
+               return ret;
+       }
+
+       public List<T> executeQuery(TypedQuery<T> qry) {
+               List<T> ret = null;
+
+               ret = qry.getResultList();
+
+               return ret;
+       }
+
+       public List<T> findByNamedQuery(String namedQuery, String paramName,
+                       Object refId) {
+               List<T> ret = new ArrayList<T>();
+
+               if (namedQuery == null) {
+                       return ret;
+               }
+               try {
+                       TypedQuery<T> qry = 
getEntityManager().createNamedQuery(namedQuery, tClass);
+                       qry.setParameter(paramName, refId);
+                       ret = qry.getResultList();
+               } catch (NoResultException e) {
+                       // ignore
+               }
+               return ret;
+       }       
+       
+       public T findByAlias(String namedQuery, String alias) {
+               try {
+                       return getEntityManager()
+                                       .createNamedQuery(namedQuery, tClass)
+                                       .setParameter("alias", alias)
+                                       .getSingleResult();
+               } catch (NoResultException e) {
+               }
+               return null;
+       }
+       
+       public int deleteByAlias(String namedQuery, String alias) {
+               boolean trxBegan = beginTransaction();
+               try {
+                       int i = getEntityManager()
+                                       .createNamedQuery(namedQuery, tClass)
+                                       .setParameter("alias", 
alias).executeUpdate();
+                       if(trxBegan) {
+                               commitTransaction();
+                       }
+                       return i;
+               } catch (NoResultException e) {
+                       e.printStackTrace();
+                       rollbackTransaction();
+               }               
+               return 0;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/kms/dao/DaoManager.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/kms/dao/DaoManager.java 
b/kms/src/main/java/org/apache/ranger/kms/dao/DaoManager.java
new file mode 100644
index 0000000..be67204
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/kms/dao/DaoManager.java
@@ -0,0 +1,35 @@
+package org.apache.ranger.kms.dao;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceContext;
+
+public class DaoManager extends DaoManagerBase {
+
+       @PersistenceContext
+       private EntityManagerFactory emf;
+
+       static ThreadLocal<EntityManager> sEntityManager;
+
+       public void setEntityManagerFactory(EntityManagerFactory emf) {
+               this.emf = emf;
+               sEntityManager = new ThreadLocal<EntityManager>();
+       }
+
+       @Override
+       public EntityManager getEntityManager() {
+               EntityManager em = null;
+
+               if(sEntityManager != null) {
+                       em = sEntityManager.get();
+
+                       if(em == null && this.emf != null) {
+                               em = this.emf.createEntityManager();
+
+                               sEntityManager.set(em);
+                       }
+               }
+
+               return em;
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/kms/dao/DaoManagerBase.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/kms/dao/DaoManagerBase.java 
b/kms/src/main/java/org/apache/ranger/kms/dao/DaoManagerBase.java
new file mode 100644
index 0000000..5cd84b0
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/kms/dao/DaoManagerBase.java
@@ -0,0 +1,31 @@
+package org.apache.ranger.kms.dao;
+
+import javax.persistence.EntityManager;
+import org.apache.log4j.Logger;
+
+public abstract class DaoManagerBase {
+       final static Logger logger = Logger.getLogger(DaoManagerBase.class);
+
+       abstract public EntityManager getEntityManager();
+
+       private RangerMasterKeyDao rangerMasterKeyDao = null;
+       private RangerKMSDao rangerKmsDao = null;
+
+    public DaoManagerBase() {
+       }
+
+       public RangerMasterKeyDao getRangerMasterKeyDao() {
+               if(rangerMasterKeyDao == null) {
+                       rangerMasterKeyDao = new RangerMasterKeyDao(this);
+               }
+
+               return rangerMasterKeyDao;
+       }
+       
+       public RangerKMSDao getRangerKMSDao(){
+               if(rangerKmsDao == null){
+                       rangerKmsDao = new RangerKMSDao(this);
+               }
+               return rangerKmsDao;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/kms/dao/RangerKMSDao.java
----------------------------------------------------------------------
diff --git a/kms/src/main/java/org/apache/ranger/kms/dao/RangerKMSDao.java 
b/kms/src/main/java/org/apache/ranger/kms/dao/RangerKMSDao.java
new file mode 100644
index 0000000..d5c94fe
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/kms/dao/RangerKMSDao.java
@@ -0,0 +1,18 @@
+package org.apache.ranger.kms.dao;
+
+import org.apache.ranger.entity.XXRangerKeyStore;
+
+public class RangerKMSDao extends BaseDao<XXRangerKeyStore> {
+
+       public RangerKMSDao(DaoManagerBase daoManager) {
+               super(daoManager);
+       }
+       
+       public XXRangerKeyStore findByAlias(String alias){
+               return super.findByAlias("XXRangerKeyStore.findByAlias", alias);
+       }
+       
+       public int deleteByAlias(String alias){
+               return super.deleteByAlias("XXRangerKeyStore.deleteByAlias", 
alias);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/java/org/apache/ranger/kms/dao/RangerMasterKeyDao.java
----------------------------------------------------------------------
diff --git 
a/kms/src/main/java/org/apache/ranger/kms/dao/RangerMasterKeyDao.java 
b/kms/src/main/java/org/apache/ranger/kms/dao/RangerMasterKeyDao.java
new file mode 100644
index 0000000..4170433
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/kms/dao/RangerMasterKeyDao.java
@@ -0,0 +1,10 @@
+package org.apache.ranger.kms.dao;
+
+import org.apache.ranger.entity.XXRangerMasterKey;
+
+public class RangerMasterKeyDao extends BaseDao<XXRangerMasterKey> {
+
+       public RangerMasterKeyDao(DaoManagerBase daoManager) {
+               super(daoManager);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/resources/META-INF/kms_jpa_named_queries.xml
----------------------------------------------------------------------
diff --git a/kms/src/main/resources/META-INF/kms_jpa_named_queries.xml 
b/kms/src/main/resources/META-INF/kms_jpa_named_queries.xml
new file mode 100644
index 0000000..8fd3128
--- /dev/null
+++ b/kms/src/main/resources/META-INF/kms_jpa_named_queries.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+<entity-mappings version="1.0"
+       xmlns="http://java.sun.com/xml/ns/persistence/orm"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm 
http://java.sun.com/xml/ns/persistence/orm_1_0.xsd ">
+       <named-query name="XXRangerKeyStore.findByAlias">
+               <query>SELECT Obj FROM XXRangerKeyStore obj
+                          WHERE obj.alias=:alias
+               </query>
+       </named-query>
+
+       <named-query name="XXRangerKeyStore.deleteByAlias">
+               <query>DELETE FROM XXRangerKeyStore obj
+                          WHERE obj.alias=:alias
+               </query>
+       </named-query>
+</entity-mappings>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/kms/src/main/resources/META-INF/persistence.xml 
b/kms/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000..31c0bc4
--- /dev/null
+++ b/kms/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,28 @@
+<?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.
+-->
+<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd";>
+       <persistence-unit name="persistence_ranger_server">
+               <mapping-file>META-INF/kms_jpa_named_queries.xml</mapping-file>
+               <class>org.apache.ranger.entity.XXRangerMasterKey</class>
+               <class>org.apache.ranger.entity.XXRangerKeyStore</class>
+
+               <properties>
+                       <property name="eclipselink.logging.level" 
value="SEVERE"/>
+               </properties>
+       </persistence-unit>
+</persistence>

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/resources/META-INF/services/org.apache.hadoop.crypto.key.KeyProviderFactory
----------------------------------------------------------------------
diff --git 
a/kms/src/main/resources/META-INF/services/org.apache.hadoop.crypto.key.KeyProviderFactory
 
b/kms/src/main/resources/META-INF/services/org.apache.hadoop.crypto.key.KeyProviderFactory
new file mode 100644
index 0000000..bb9f0bb
--- /dev/null
+++ 
b/kms/src/main/resources/META-INF/services/org.apache.hadoop.crypto.key.KeyProviderFactory
@@ -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.crypto.key.RangerKeyStoreProvider$Factory
+org.apache.hadoop.crypto.key.JavaKeyStoreProvider$Factory
+org.apache.hadoop.crypto.key.UserProvider$Factory
+org.apache.hadoop.crypto.key.kms.KMSClientProvider$Factory

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/resources/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/kms/src/main/resources/WEB-INF/web.xml 
b/kms/src/main/resources/WEB-INF/web.xml
new file mode 100644
index 0000000..71c580c
--- /dev/null
+++ b/kms/src/main/resources/WEB-INF/web.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee";>
+
+  <display-name>ranger-kms</display-name>
+
+  <listener>
+    
<listener-class>org.apache.hadoop.crypto.key.kms.server.KMSWebApp</listener-class>
+  </listener>
+
+  <servlet>
+    <servlet-name>webservices-driver</servlet-name>
+    
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+    <init-param>
+      <param-name>com.sun.jersey.config.property.packages</param-name>
+      <param-value>org.apache.hadoop.crypto.key.kms.server</param-value>
+    </init-param>
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+  
+<!--   <servlet>
+    <servlet-name>RangerKMSStartUp</servlet-name>
+    <servlet-class>org.apache.ranger.kms.biz.RangerKMSStartUp</servlet-class>  
  
+    <load-on-startup>2</load-on-startup>
+  </servlet> -->
+
+  <servlet>
+    <servlet-name>jmx-servlet</servlet-name>
+    
<servlet-class>org.apache.hadoop.crypto.key.kms.server.KMSJMXServlet</servlet-class>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>webservices-driver</servlet-name>
+    <url-pattern>/*</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>jmx-servlet</servlet-name>
+    <url-pattern>/jmx</url-pattern>
+  </servlet-mapping>
+
+  <filter>
+    <filter-name>authFilter</filter-name>
+    
<filter-class>org.apache.hadoop.crypto.key.kms.server.KMSAuthenticationFilter</filter-class>
+  </filter>
+
+  <filter>
+    <filter-name>MDCFilter</filter-name>
+    
<filter-class>org.apache.hadoop.crypto.key.kms.server.KMSMDCFilter</filter-class>
+  </filter>
+
+  <filter-mapping>
+    <filter-name>authFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
+
+  <filter-mapping>
+    <filter-name>MDCFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
+
+</web-app>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/resources/log4j-kmsaudit.properties
----------------------------------------------------------------------
diff --git a/kms/src/main/resources/log4j-kmsaudit.properties 
b/kms/src/main/resources/log4j-kmsaudit.properties
new file mode 100644
index 0000000..cca6941
--- /dev/null
+++ b/kms/src/main/resources/log4j-kmsaudit.properties
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+
+# LOG Appender
+log4j.appender.kms-audit=org.apache.log4j.ConsoleAppender
+log4j.appender.kms-audit.Target=System.err
+log4j.appender.kms-audit.layout=org.apache.log4j.PatternLayout
+log4j.appender.kms-audit.layout.ConversionPattern=%m
+
+log4j.rootLogger=INFO, kms-audit
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/kms/src/main/resources/log4j.properties 
b/kms/src/main/resources/log4j.properties
new file mode 100644
index 0000000..5cd037a
--- /dev/null
+++ b/kms/src/main/resources/log4j.properties
@@ -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.
+#
+
+# STDOUT Appender
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %-5p %c{1} - %m%n
+
+log4j.rootLogger=WARN, stdout
+log4j.logger.org.apache.hadoop.conf=ERROR
+log4j.logger.org.apache.hadoop.crytpo.key.kms.server=ALL
+log4j.logger.com.sun.jersey.server.wadl.generators.WadlGeneratorJAXBGrammarGenerator=OFF
+log4j.logger.org.apache.hadoop.security=OFF
+log4j.logger.org.apache.directory.server.core=OFF
+log4j.logger.org.apache.hadoop.util.NativeCodeLoader=OFF
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/resources/mini-kms-acls-default.xml
----------------------------------------------------------------------
diff --git a/kms/src/main/resources/mini-kms-acls-default.xml 
b/kms/src/main/resources/mini-kms-acls-default.xml
new file mode 100644
index 0000000..24a46b8
--- /dev/null
+++ b/kms/src/main/resources/mini-kms-acls-default.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed 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.
+-->
+<configuration>
+
+  <!-- This file is hot-reloaded when it changes -->
+
+  <!-- KMS ACLs -->
+
+  <property>
+    <name>hadoop.kms.acl.CREATE</name>
+    <value>*</value>
+    <description>
+      ACL for create-key operations.
+      If the user does is not in the GET ACL, the key material is not returned
+      as part of the response.
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.DELETE</name>
+    <value>*</value>
+    <description>
+      ACL for delete-key operations.
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.ROLLOVER</name>
+    <value>*</value>
+    <description>
+      ACL for rollover-key operations.
+      If the user does is not in the GET ACL, the key material is not returned
+      as part of the response.
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.GET</name>
+    <value>*</value>
+    <description>
+      ACL for get-key-version and get-current-key operations.
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.GET_KEYS</name>
+    <value>*</value>
+    <description>
+      ACL for get-keys operation.
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.GET_METADATA</name>
+    <value>*</value>
+    <description>
+      ACL for get-key-metadata an get-keys-metadata operations.
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.SET_KEY_MATERIAL</name>
+    <value>*</value>
+    <description>
+      Complimentary ACL for CREATE and ROLLOVER operation to allow the client
+      to provide the key material when creating or rolling a key.
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.GENERATE_EEK</name>
+    <value>*</value>
+    <description>
+      ACL for generateEncryptedKey CryptoExtension operations
+    </description>
+  </property>
+
+  <property>
+    <name>hadoop.kms.acl.DECRYPT_EEK</name>
+    <value>*</value>
+    <description>
+      ACL for decrypt EncryptedKey CryptoExtension operations
+    </description>
+  </property>
+
+  <property>
+    <name>default.key.acl.MANAGEMENT</name>
+    <value>*</value>
+    <description>
+      default ACL for MANAGEMENT operations for all key acls that are not
+      explicitly defined.
+    </description>
+  </property>
+
+  <property>
+    <name>default.key.acl.GENERATE_EEK</name>
+    <value>*</value>
+    <description>
+      default ACL for GENERATE_EEK operations for all key acls that are not
+      explicitly defined.
+    </description>
+  </property>
+
+  <property>
+    <name>default.key.acl.DECRYPT_EEK</name>
+    <value>*</value>
+    <description>
+      default ACL for DECRYPT_EEK operations for all key acls that are not
+      explicitly defined.
+    </description>
+  </property>
+
+  <property>
+    <name>default.key.acl.READ</name>
+    <value>*</value>
+    <description>
+      default ACL for READ operations for all key acls that are not
+      explicitly defined.
+    </description>
+  </property>
+
+
+</configuration>

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/kms/src/main/webapp/WEB-INF/web.xml 
b/kms/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..7d87e90
--- /dev/null
+++ b/kms/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee";>
+
+  <display-name>ranger-kms</display-name>
+
+  <listener>
+    
<listener-class>org.apache.hadoop.crypto.key.kms.server.KMSWebApp</listener-class>
+  </listener>
+
+  <servlet>
+    <servlet-name>webservices-driver</servlet-name>
+    
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
+    <init-param>
+      <param-name>com.sun.jersey.config.property.packages</param-name>
+      <param-value>org.apache.hadoop.crypto.key.kms.server</param-value>
+    </init-param>
+    <load-on-startup>1</load-on-startup>
+  </servlet>
+  
+  <!-- <servlet>
+    <servlet-name>RangerKMSStartUp</servlet-name>
+    <servlet-class>org.apache.ranger.kms.biz.RangerKMSStartUp</servlet-class>  
  
+    <load-on-startup>2</load-on-startup>
+  </servlet> -->
+
+  <servlet>
+    <servlet-name>jmx-servlet</servlet-name>
+    
<servlet-class>org.apache.hadoop.crypto.key.kms.server.KMSJMXServlet</servlet-class>
+  </servlet>
+
+  <servlet-mapping>
+    <servlet-name>webservices-driver</servlet-name>
+    <url-pattern>/*</url-pattern>
+  </servlet-mapping>
+
+  <servlet-mapping>
+    <servlet-name>jmx-servlet</servlet-name>
+    <url-pattern>/jmx</url-pattern>
+  </servlet-mapping>
+
+  <filter>
+    <filter-name>authFilter</filter-name>
+    
<filter-class>org.apache.hadoop.crypto.key.kms.server.KMSAuthenticationFilter</filter-class>
+  </filter>
+
+  <filter>
+    <filter-name>MDCFilter</filter-name>
+    
<filter-class>org.apache.hadoop.crypto.key.kms.server.KMSMDCFilter</filter-class>
+  </filter>
+
+  <filter-mapping>
+    <filter-name>authFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
+
+  <filter-mapping>
+    <filter-name>MDCFilter</filter-name>
+    <url-pattern>/*</url-pattern>
+  </filter-mapping>
+
+</web-app>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/MiniKMS.java
----------------------------------------------------------------------
diff --git 
a/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/MiniKMS.java 
b/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/MiniKMS.java
new file mode 100644
index 0000000..4f802cc
--- /dev/null
+++ b/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/MiniKMS.java
@@ -0,0 +1,238 @@
+/**
+ * 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.crypto.key.kms.server;
+
+import com.google.common.base.Preconditions;
+import org.apache.commons.io.IOUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.crypto.key.kms.KMSRESTConstants;
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.security.ssl.SslSocketConnectorSecure;
+import org.mortbay.jetty.Connector;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.security.SslSocketConnector;
+import org.mortbay.jetty.webapp.WebAppContext;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.ServerSocket;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.UUID;
+
+public class MiniKMS {
+
+  private static Server createJettyServer(String keyStore, String password, 
int inPort) {
+    try {
+      boolean ssl = keyStore != null;
+      InetAddress localhost = InetAddress.getByName("localhost");
+      String host = "localhost";
+      ServerSocket ss = new ServerSocket((inPort < 0) ? 0 : inPort, 50, 
localhost);
+      int port = ss.getLocalPort();
+      ss.close();
+      Server server = new Server(0);
+      if (!ssl) {
+        server.getConnectors()[0].setHost(host);
+        server.getConnectors()[0].setPort(port);
+      } else {
+        SslSocketConnector c = new SslSocketConnectorSecure();
+        c.setHost(host);
+        c.setPort(port);
+        c.setNeedClientAuth(false);
+        c.setKeystore(keyStore);
+        c.setKeystoreType("jks");
+        c.setKeyPassword(password);
+        server.setConnectors(new Connector[]{c});
+      }
+      return server;
+    } catch (Exception ex) {
+      throw new RuntimeException("Could not start embedded servlet container, "
+          + ex.getMessage(), ex);
+    }
+  }
+
+  private static URL getJettyURL(Server server) {
+    boolean ssl = server.getConnectors()[0].getClass()
+        == SslSocketConnectorSecure.class;
+    try {
+      String scheme = (ssl) ? "https" : "http";
+      return new URL(scheme + "://" +
+          server.getConnectors()[0].getHost() + ":" +
+          server.getConnectors()[0].getPort());
+    } catch (MalformedURLException ex) {
+      throw new RuntimeException("It should never happen, " + ex.getMessage(),
+          ex);
+    }
+  }
+
+  public static class Builder {
+    private File kmsConfDir;
+    private String log4jConfFile;
+    private File keyStoreFile;
+    private String keyStorePassword;
+    private int inPort = -1;
+
+    public Builder() {
+      kmsConfDir = new File("target/test-classes").getAbsoluteFile();
+      log4jConfFile = "kms-log4j.properties";
+    }
+
+    public Builder setKmsConfDir(File confDir) {
+      Preconditions.checkNotNull(confDir, "KMS conf dir is NULL");
+      Preconditions.checkArgument(confDir.exists(),
+          "KMS conf dir does not exist");
+      kmsConfDir = confDir;
+      return this;
+    }
+
+    public Builder setLog4jConfFile(String log4jConfFile) {
+      Preconditions.checkNotNull(log4jConfFile, "log4jconf file is NULL");
+      this.log4jConfFile = log4jConfFile;
+      return this;
+    }
+
+    public Builder setPort(int port) {
+      Preconditions.checkArgument(port > 0, "input port must be greater than 
0");
+      this.inPort = port;
+      return this;
+    }
+
+    public Builder setSslConf(File keyStoreFile, String keyStorePassword) {
+      Preconditions.checkNotNull(keyStoreFile, "keystore file is NULL");
+      Preconditions.checkNotNull(keyStorePassword, "keystore password is 
NULL");
+      Preconditions.checkArgument(keyStoreFile.exists(),
+          "keystore file does not exist");
+      this.keyStoreFile = keyStoreFile;
+      this.keyStorePassword = keyStorePassword;
+      return this;
+    }
+
+    public MiniKMS build() {
+      Preconditions.checkArgument(kmsConfDir.exists(),
+          "KMS conf dir does not exist");
+      return new MiniKMS(kmsConfDir.getAbsolutePath(), log4jConfFile,
+          (keyStoreFile != null) ? keyStoreFile.getAbsolutePath() : null,
+          keyStorePassword, inPort);
+    }
+  }
+
+  private String kmsConfDir;
+  private String log4jConfFile;
+  private String keyStore;
+  private String keyStorePassword;
+  private Server jetty;
+  private int inPort;
+  private URL kmsURL;
+
+  public MiniKMS(String kmsConfDir, String log4ConfFile, String keyStore,
+      String password, int inPort) {
+    this.kmsConfDir = kmsConfDir;
+    this.log4jConfFile = log4ConfFile;
+    this.keyStore = keyStore;
+    this.keyStorePassword = password;
+    this.inPort = inPort;
+  }
+
+  public void start() throws Exception {
+    ClassLoader cl = Thread.currentThread().getContextClassLoader();
+    System.setProperty(KMSConfiguration.KMS_CONFIG_DIR, kmsConfDir);
+    File aclsFile = new File(kmsConfDir, "kms-acls.xml");
+    if (!aclsFile.exists()) {
+      InputStream is = cl.getResourceAsStream("mini-kms-acls-default.xml");
+      OutputStream os = new FileOutputStream(aclsFile);
+      IOUtils.copy(is, os);
+      is.close();
+      os.close();
+    }
+    File coreFile = new File(kmsConfDir, "core-site.xml");
+    if (!coreFile.exists()) {
+      Configuration core = new Configuration();
+      Writer writer = new FileWriter(coreFile);
+      core.writeXml(writer);
+      writer.close();
+    }
+    File kmsFile = new File(kmsConfDir, "kms-site.xml");
+    if (!kmsFile.exists()) {
+      Configuration kms = new Configuration(false);
+      kms.set(KMSConfiguration.KEY_PROVIDER_URI,
+          "jceks://file@" + new Path(kmsConfDir, "kms.keystore").toUri());
+      kms.set("hadoop.kms.authentication.type", "simple");
+      Writer writer = new FileWriter(kmsFile);
+      kms.writeXml(writer);
+      writer.close();
+    }
+    System.setProperty("log4j.configuration", log4jConfFile);
+    jetty = createJettyServer(keyStore, keyStorePassword, inPort);
+
+    // we need to do a special handling for MiniKMS to work when in a dir and
+    // when in a JAR in the classpath thanks to Jetty way of handling of 
webapps
+    // when they are in the a DIR, WAR or JAR.
+    URL webXmlUrl = cl.getResource("kms-webapp/WEB-INF/web.xml");
+    if (webXmlUrl == null) {
+      throw new RuntimeException(
+          "Could not find kms-webapp/ dir in test classpath");
+    }
+    boolean webXmlInJar = webXmlUrl.getPath().contains(".jar!/");
+    String webappPath;
+    if (webXmlInJar) {
+      File webInf = new File("target/" + UUID.randomUUID().toString() +
+          "/kms-webapp/WEB-INF");
+      webInf.mkdirs();
+      new File(webInf, "web.xml").delete();
+      InputStream is = cl.getResourceAsStream("kms-webapp/WEB-INF/web.xml");
+      OutputStream os = new FileOutputStream(new File(webInf, "web.xml"));
+      IOUtils.copy(is, os);
+      is.close();
+      os.close();
+      webappPath = webInf.getParentFile().getAbsolutePath();
+    } else {
+      webappPath = cl.getResource("kms-webapp").getPath();
+    }
+    WebAppContext context = new WebAppContext(webappPath, "/kms");
+    if (webXmlInJar) {
+      context.setClassLoader(cl);
+    }
+    jetty.addHandler(context);
+    jetty.start();
+    kmsURL = new URL(getJettyURL(jetty), "kms");
+  }
+
+  public URL getKMSUrl() {
+    return kmsURL;
+  }
+
+  public void stop() {
+    if (jetty != null && jetty.isRunning()) {
+      try {
+        jetty.stop();
+        jetty = null;
+      } catch (Exception ex) {
+        throw new RuntimeException("Could not stop MiniKMS embedded Jetty, " +
+            ex.getMessage(), ex);
+      }
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/bb0bdced/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMSACLs.java
----------------------------------------------------------------------
diff --git 
a/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMSACLs.java 
b/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMSACLs.java
new file mode 100644
index 0000000..12945d7
--- /dev/null
+++ b/kms/src/test/java/org/apache/hadoop/crypto/key/kms/server/TestKMSACLs.java
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.crypto.key.kms.server;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.crypto.key.kms.server.KMSACLsType.Type;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestKMSACLs {
+
+  @Test
+  public void testDefaults() {
+    KMSACLs acls = new KMSACLs(new Configuration(false));
+    for (Type type : Type.values()) {
+      Assert.assertTrue(acls.hasAccess(type,
+          UserGroupInformation.createRemoteUser("foo")));
+    }
+  }
+
+  @Test
+  public void testCustom() {
+    Configuration conf = new Configuration(false);
+    for (Type type : Type.values()) {
+      conf.set(type.getAclConfigKey(), type.toString() + " ");
+    }
+    KMSACLs acls = new KMSACLs(conf);
+    for (Type type : Type.values()) {
+      Assert.assertTrue(acls.hasAccess(type,
+          UserGroupInformation.createRemoteUser(type.toString())));
+      Assert.assertFalse(acls.hasAccess(type,
+          UserGroupInformation.createRemoteUser("foo")));
+    }
+  }
+
+}

Reply via email to