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

madhan pushed a commit to branch ranger-2.8
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/ranger-2.8 by this push:
     new aa44a5e2f RANGER-5517: remove ranger-plugins-common dependency from 
kms, embeddedwebserver and shim modules (#876)
aa44a5e2f is described below

commit aa44a5e2fe71f5902f03cbcea129225a19cb481b
Author: Madhan Neethiraj <[email protected]>
AuthorDate: Wed Mar 18 11:22:36 2026 -0700

    RANGER-5517: remove ranger-plugins-common dependency from kms, 
embeddedwebserver and shim modules (#876)
    
    (cherry picked from commit 2702a2fa000bd537af2073f719add71a7481d55d)
    (cherry picked from commit f8e9f122081abe2c2e250f55b9669ed959c02f42)
---
 distro/src/main/assembly/kms.xml                   |   4 +-
 embeddedwebserver/pom.xml                          |   5 -
 .../security/KrbPasswordSaverLoginModule.java      |  76 ++++++++
 .../apache/hadoop/security/SecureClientLogin.java  | 195 +++++++++++++++++++++
 .../org/apache/ranger/plugin/util/XMLUtils.java    | 142 +++++++++++++++
 .../server/tomcat/SolrCollectionBootstrapper.java  |   3 +-
 kms/pom.xml                                        |  44 -----
 .../ranger/plugin/util/AutoClosableLock.java       | 116 ++++++++++++
 .../org/apache/ranger/plugin/util/JsonUtilsV2.java |  89 ++++++++++
 .../org/apache/ranger/plugin/util/XMLUtils.java    | 142 +++++++++++++++
 ranger-atlas-plugin-shim/pom.xml                   |   5 -
 ranger-hbase-plugin-shim/pom.xml                   |   5 -
 ranger-hdfs-plugin-shim/pom.xml                    |   5 -
 ranger-hive-plugin-shim/pom.xml                    |   5 -
 ranger-kafka-plugin-shim/pom.xml                   |   5 -
 ranger-kms-plugin-shim/pom.xml                     |   5 -
 ranger-knox-plugin-shim/pom.xml                    |   5 -
 ranger-kylin-plugin-shim/pom.xml                   |   5 -
 ranger-ozone-plugin-shim/pom.xml                   |   5 -
 ranger-presto-plugin-shim/pom.xml                  |   6 -
 ranger-solr-plugin-shim/pom.xml                    |   5 -
 ranger-sqoop-plugin-shim/pom.xml                   |   5 -
 ranger-storm-plugin-shim/pom.xml                   |   5 -
 ranger-yarn-plugin-shim/pom.xml                    |   5 -
 24 files changed, 762 insertions(+), 125 deletions(-)

diff --git a/distro/src/main/assembly/kms.xml b/distro/src/main/assembly/kms.xml
index a24ecc501..47791ce57 100755
--- a/distro/src/main/assembly/kms.xml
+++ b/distro/src/main/assembly/kms.xml
@@ -42,6 +42,7 @@
                     
<include>org.apache.hadoop.thirdparty:hadoop-shaded-guava:jar:${hadoop-shaded-guava.version}</include>
                     
<include>org.apache.hadoop:hadoop-auth:jar:${hadoop.version}</include>
                     <include>com.google.code.gson:gson</include>
+                    <include>com.sun.jersey:jersey-bundle</include>
                     <include>org.eclipse.persistence:eclipselink</include>
                     
<include>org.eclipse.persistence:javax.persistence</include>
                     <include>com.googlecode.log4jdbc:log4jdbc</include>
@@ -214,8 +215,6 @@
                     
<include>org.apache.hadoop:hadoop-client-api:jar:${hadoop.version}</include>
                     
<include>org.apache.hadoop:hadoop-client-runtime:jar:${hadoop.version}</include>
                     
<include>org.apache.solr:solr-solrj:jar:${solr.version}</include>
-                    <include>org.apache.ranger:ranger-authz-api</include>
-                    <include>org.apache.ranger:ranger-plugins-common</include>
                     <include>org.apache.ranger:ugsync-util</include>
                     
<include>com.kstruct:gethostname4j:jar:${kstruct.gethostname4j.version}</include>
                     <include>net.java.dev.jna:jna:jar:${jna.version}</include>
@@ -230,7 +229,6 @@
                     <include>org.slf4j:slf4j-api</include>
                     
<include>ch.qos.logback:logback-classic:jar:${logback.version}</include>
                     
<include>ch.qos.logback:logback-core:jar:${logback.version}</include>
-                    <include>com.sun.jersey:jersey-bundle</include>
                     
<include>com.fasterxml.jackson.core:jackson-annotations:jar:${fasterxml.jackson.version}</include>
                     
<include>com.fasterxml.jackson.core:jackson-core:jar:${fasterxml.jackson.version}</include>
                     
<include>com.fasterxml.jackson.core:jackson-databind:jar:${fasterxml.jackson.version}</include>
diff --git a/embeddedwebserver/pom.xml b/embeddedwebserver/pom.xml
index 946f7b0a0..f1b8a03c3 100644
--- a/embeddedwebserver/pom.xml
+++ b/embeddedwebserver/pom.xml
@@ -88,11 +88,6 @@
             <artifactId>ranger-audit-dest-solr</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
         <dependency>
             <groupId>org.apache.tomcat</groupId>
             <artifactId>tomcat-annotations-api</artifactId>
diff --git 
a/embeddedwebserver/src/main/java/org/apache/hadoop/security/KrbPasswordSaverLoginModule.java
 
b/embeddedwebserver/src/main/java/org/apache/hadoop/security/KrbPasswordSaverLoginModule.java
new file mode 100644
index 000000000..c1912aa43
--- /dev/null
+++ 
b/embeddedwebserver/src/main/java/org/apache/hadoop/security/KrbPasswordSaverLoginModule.java
@@ -0,0 +1,76 @@
+/*
+ * 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.security;
+
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+
+public class KrbPasswordSaverLoginModule implements LoginModule {
+    public static final String USERNAME_PARAM = 
"javax.security.auth.login.name";
+    public static final String PASSWORD_PARAM = 
"javax.security.auth.login.password";
+
+       @SuppressWarnings("rawtypes")
+       private Map sharedState;
+
+       public KrbPasswordSaverLoginModule() {
+       }
+
+       @Override
+       public boolean abort() throws LoginException {
+               return true;
+       }
+
+       @Override
+       public boolean commit() throws LoginException {
+               return true;
+       }
+
+       @SuppressWarnings("unchecked")
+       @Override
+       public void initialize(Subject subject, CallbackHandler 
callbackhandler, Map<String, ?> sharedMap, Map<String, ?> options) {
+
+               this.sharedState = sharedMap;
+
+               String userName = (options != null) ? 
(String)options.get(USERNAME_PARAM) : null;
+               if (userName != null) {
+                       this.sharedState.put(USERNAME_PARAM,userName);
+               }
+               String password = (options != null) ? 
(String)options.get(PASSWORD_PARAM) : null;
+
+               if (password != null) {
+                       
this.sharedState.put(PASSWORD_PARAM,password.toCharArray());
+               }
+       }
+
+       @Override
+       public boolean login() throws LoginException {
+               return true;
+       }
+
+       @Override
+       public boolean logout() throws LoginException {
+               return true;
+       }
+
+}
diff --git 
a/embeddedwebserver/src/main/java/org/apache/hadoop/security/SecureClientLogin.java
 
b/embeddedwebserver/src/main/java/org/apache/hadoop/security/SecureClientLogin.java
new file mode 100644
index 000000000..a0dc619c2
--- /dev/null
+++ 
b/embeddedwebserver/src/main/java/org/apache/hadoop/security/SecureClientLogin.java
@@ -0,0 +1,195 @@
+/*
+ * 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.security;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
+import org.apache.hadoop.security.authentication.util.KerberosUtil;
+import org.apache.hadoop.security.authentication.util.KerberosName;
+import org.apache.hadoop.util.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SecureClientLogin {
+       private static final Logger LOG = 
LoggerFactory.getLogger(SecureClientLogin.class);
+       public static final String HOSTNAME_PATTERN = "_HOST";
+
+       public synchronized static Subject loginUserFromKeytab(String user, 
String path) throws IOException {
+               try {
+                       Subject subject = new Subject();
+                       SecureClientLoginConfiguration loginConf = new 
SecureClientLoginConfiguration(true, user, path);
+                       LoginContext login = new 
LoginContext("hadoop-keytab-kerberos", subject, null, loginConf);
+                       subject.getPrincipals().add(new User(user, 
AuthenticationMethod.KERBEROS, login));
+                       login.login();
+                       return login.getSubject();
+               } catch (LoginException le) {
+                       throw new IOException("Login failure for " + user + " 
from keytab " + path, le);
+               }
+       }
+
+       public synchronized static Subject loginUserFromKeytab(String user, 
String path, String nameRules) throws IOException {
+               try {
+                       Subject subject = new Subject();
+                       SecureClientLoginConfiguration loginConf = new 
SecureClientLoginConfiguration(true, user, path);
+                       LoginContext login = new 
LoginContext("hadoop-keytab-kerberos", subject, null, loginConf);
+                       KerberosName.setRules(nameRules);
+                       subject.getPrincipals().add(new User(user, 
AuthenticationMethod.KERBEROS, login));
+                       login.login();
+                       return login.getSubject();
+               } catch (LoginException le) {
+                       throw new IOException("Login failure for " + user + " 
from keytab " + path, le);
+               }
+       }
+
+       public synchronized static Subject loginUserWithPassword(String user, 
String password) throws IOException {
+               try {
+                       Subject subject = new Subject();
+                       SecureClientLoginConfiguration loginConf = new 
SecureClientLoginConfiguration(false, user, password);
+                       LoginContext login = new 
LoginContext("hadoop-keytab-kerberos", subject, null, loginConf);
+                       subject.getPrincipals().add(new User(user, 
AuthenticationMethod.KERBEROS, login));
+                       login.login();
+                       return login.getSubject();
+               } catch (LoginException le) {
+                       throw new IOException("Login failure for " + user + " 
using password ****", le);
+               }
+       }
+
+       public synchronized static Subject login(String user) throws 
IOException {
+               Subject subject = new Subject();
+               subject.getPrincipals().add(new User(user));
+               return subject;
+       }
+
+       public static Set<Principal> getUserPrincipals(Subject aSubject) {
+               if (aSubject != null) {
+                       Set<User> list = aSubject.getPrincipals(User.class);
+                       if (list != null) {
+                               Set<Principal> ret = new HashSet<>();
+                               ret.addAll(list);
+                               return ret;
+                       } else {
+                               return null;
+                       }
+               } else {
+                       return null;
+               }
+       }
+
+       public static Principal createUserPrincipal(String aLoginName) {
+               return new User(aLoginName);
+       }
+
+       public static boolean isKerberosCredentialExists(String principal, 
String keytabPath){
+               boolean isValid = false;
+               if (keytabPath != null && !keytabPath.isEmpty()) {
+                       File keytabFile = new File(keytabPath);
+                       if (!keytabFile.exists()) {
+                               LOG.warn(keytabPath + " doesn't exist.");
+                       } else if (!keytabFile.canRead()) {
+                               LOG.warn("Unable to read " + keytabPath + ". 
Please check the file access permissions for user");
+                       }else{
+                               isValid = true;
+                       }
+               } else {
+                       LOG.warn("Can't find keyTab Path : "+keytabPath);
+               }
+               if (!(principal != null && !principal.isEmpty() && isValid)) {
+                       isValid = false;
+                       LOG.warn("Can't find principal : "+principal);
+               }
+               return isValid;
+       }
+
+       public static String getPrincipal(String principalConfig, String 
hostName) throws IOException {
+               String[] components = getComponents(principalConfig);
+               if (components == null || components.length != 3 || 
!HOSTNAME_PATTERN.equals(components[1])) {
+                       return principalConfig;
+               } else {
+                       if (hostName == null) {
+                               throw new IOException("Can't replace " + 
HOSTNAME_PATTERN + " pattern since client ranger.service.host is null");
+                       }
+                       return replacePattern(components, hostName);
+               }
+       }
+
+       private static String[] getComponents(String principalConfig) {
+               if (principalConfig == null)
+                       return null;
+               return principalConfig.split("[/@]");
+       }
+
+       private static String replacePattern(String[] components, String 
hostname)
+                       throws IOException {
+               String fqdn = hostname;
+               if (fqdn == null || fqdn.isEmpty() || "0.0.0.0".equals(fqdn)) {
+                       fqdn = 
java.net.InetAddress.getLocalHost().getCanonicalHostName();
+               }
+               return components[0] + "/" + StringUtils.toLowerCase(fqdn) + 
"@" + components[2];
+       }
+}
+
+class SecureClientLoginConfiguration extends 
javax.security.auth.login.Configuration {
+       private Map<String, String> kerberosOptions = new HashMap<>();
+       private boolean usePassword;
+
+       public SecureClientLoginConfiguration(boolean useKeyTab, String 
principal, String credential) {
+               kerberosOptions.put("principal", principal);
+               kerberosOptions.put("debug", "false");
+               if (useKeyTab) {
+                       kerberosOptions.put("useKeyTab", "true");
+                       kerberosOptions.put("keyTab", credential);
+                       kerberosOptions.put("doNotPrompt", "true");
+               } else {
+                       usePassword = true;
+                       kerberosOptions.put("useKeyTab", "false");
+                       
kerberosOptions.put(KrbPasswordSaverLoginModule.USERNAME_PARAM, principal);
+                       
kerberosOptions.put(KrbPasswordSaverLoginModule.PASSWORD_PARAM, credential);
+                       kerberosOptions.put("doNotPrompt", "false");
+                       kerberosOptions.put("useFirstPass", "true");
+                       kerberosOptions.put("tryFirstPass","false");
+               }
+               kerberosOptions.put("storeKey", "true");
+               kerberosOptions.put("refreshKrb5Config", "true");
+       }
+
+       @Override
+       public AppConfigurationEntry[] getAppConfigurationEntry(String appName) 
{
+               AppConfigurationEntry KEYTAB_KERBEROS_LOGIN = new 
AppConfigurationEntry(KerberosUtil.getKrb5LoginModuleName(), 
LoginModuleControlFlag.REQUIRED, kerberosOptions);
+               if (usePassword) {
+                       AppConfigurationEntry KERBEROS_PWD_SAVER = new 
AppConfigurationEntry(KrbPasswordSaverLoginModule.class.getName(), 
LoginModuleControlFlag.REQUIRED, kerberosOptions);
+                       return new AppConfigurationEntry[] { 
KERBEROS_PWD_SAVER, KEYTAB_KERBEROS_LOGIN };
+               }
+               else {
+                       return new AppConfigurationEntry[] { 
KEYTAB_KERBEROS_LOGIN };
+               }
+       }
+}
diff --git 
a/embeddedwebserver/src/main/java/org/apache/ranger/plugin/util/XMLUtils.java 
b/embeddedwebserver/src/main/java/org/apache/ranger/plugin/util/XMLUtils.java
new file mode 100644
index 000000000..02ad7d616
--- /dev/null
+++ 
b/embeddedwebserver/src/main/java/org/apache/ranger/plugin/util/XMLUtils.java
@@ -0,0 +1,142 @@
+/*
+ * 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.plugin.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.util.Map;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class XMLUtils {
+
+       private static final Logger LOG = 
LoggerFactory.getLogger(XMLUtils.class);
+
+       private static final String XMLCONFIG_PROPERTY_TAGNAME = "property";
+       private static final String XMLCONFIG_NAME_TAGNAME = "name";
+       private static final String XMLCONFIG_VALUE_TAGNAME = "value";
+
+       public static void loadConfig(String configFileName, Map<Object, 
Object> properties) {
+               try (InputStream input = getFileInputStream(configFileName)) {
+                       loadConfig(input, properties);
+               } catch (Exception e) {
+                       LOG.error("Error loading : {}", configFileName, e);
+               }
+       }
+
+       public static void loadConfig(InputStream input, Map<Object, Object> 
properties) {
+               try {
+                       DocumentBuilderFactory xmlDocumentBuilderFactory = 
DocumentBuilderFactory.newInstance();
+                       
xmlDocumentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, 
true);
+                       
xmlDocumentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities";,
 false);
+            
xmlDocumentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities";,
 false);
+                       xmlDocumentBuilderFactory.setIgnoringComments(true);
+                       xmlDocumentBuilderFactory.setNamespaceAware(true);
+
+                       DocumentBuilder xmlDocumentBuilder = 
xmlDocumentBuilderFactory.newDocumentBuilder();
+                       Document xmlDocument = xmlDocumentBuilder.parse(input);
+                       xmlDocument.getDocumentElement().normalize();
+
+                       NodeList nList = 
xmlDocument.getElementsByTagName(XMLCONFIG_PROPERTY_TAGNAME);
+
+                       for (int temp = 0; temp < nList.getLength(); temp++) {
+
+                               Node nNode = nList.item(temp);
+
+                               if (nNode.getNodeType() == Node.ELEMENT_NODE) {
+
+                                       Element eElement = (Element) nNode;
+
+                                       String propertyName = "";
+                                       String propertyValue = "";
+                                       if 
(eElement.getElementsByTagName(XMLCONFIG_NAME_TAGNAME).item(0) != null) {
+                                               propertyName = 
eElement.getElementsByTagName(XMLCONFIG_NAME_TAGNAME)
+                                                               
.item(0).getTextContent().trim();
+                                       }
+                                       if 
(eElement.getElementsByTagName(XMLCONFIG_VALUE_TAGNAME).item(0) != null) {
+                                               propertyValue = 
eElement.getElementsByTagName(XMLCONFIG_VALUE_TAGNAME)
+                                                               
.item(0).getTextContent().trim();
+                                       }
+
+                                       if (properties.get(propertyName) != 
null) {
+                                               properties.remove(propertyName);
+                                       }
+
+                                       properties.put(propertyName, 
propertyValue);
+
+                               }
+                       }
+
+               } catch (Exception e) {
+                       LOG.error("Error loading : ", e);
+               }
+       }
+
+       private static InputStream getFileInputStream(String path) throws 
FileNotFoundException {
+
+               InputStream ret = null;
+
+               // Guard against path traversal attacks
+               String sanitizedPath = new File(path).getName();
+               if ("".equals(sanitizedPath)) {
+                       return null;
+               }
+               File f = new File(sanitizedPath);
+
+               if (f.exists()) {
+                       ret = new FileInputStream(f);
+               } else {
+                       ret = XMLUtils.class.getResourceAsStream(path);
+
+                       if (ret == null) {
+                               if (! path.startsWith("/")) {
+                                       ret = 
XMLUtils.class.getResourceAsStream("/" + path);
+                               }
+                       }
+
+                       if (ret == null) {
+                               ret = 
ClassLoader.getSystemClassLoader().getResourceAsStream(path);
+                               if (ret == null) {
+                                       if (! path.startsWith("/")) {
+                                               ret = 
ClassLoader.getSystemResourceAsStream("/" + path);
+                                       }
+                               }
+                       }
+               }
+
+               if (ret == null) {
+                       throw new FileNotFoundException(path + " is not found");
+               }
+
+               return ret;
+       }
+
+}
diff --git 
a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/SolrCollectionBootstrapper.java
 
b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/SolrCollectionBootstrapper.java
index b68a8c8cb..8c8fc8f0a 100644
--- 
a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/SolrCollectionBootstrapper.java
+++ 
b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/SolrCollectionBootstrapper.java
@@ -43,7 +43,6 @@
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.entity.ByteArrayEntity;
 import org.apache.http.util.EntityUtils;
-import org.apache.ranger.authorization.utils.StringUtil;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrServerException;
 import org.apache.solr.client.solrj.impl.CloudSolrClient;
@@ -460,7 +459,7 @@ private File getConfigSetFolder() {
        private static List<String> getZkHosts() {
                String zkHosts = "";
                List<String> zookeeperHosts = null;
-               if 
(!StringUtil.isEmpty(EmbeddedServerUtil.getConfig(SOLR_ZK_HOSTS))) {
+               if 
(!StringUtils.isEmpty(EmbeddedServerUtil.getConfig(SOLR_ZK_HOSTS))) {
                        zkHosts = 
EmbeddedServerUtil.getConfig(SOLR_ZK_HOSTS).trim();
                        zookeeperHosts = new 
ArrayList<String>(Arrays.asList(zkHosts.split(",")));
                }
diff --git a/kms/pom.xml b/kms/pom.xml
index 975afecdf..d03125506 100644
--- a/kms/pom.xml
+++ b/kms/pom.xml
@@ -202,35 +202,6 @@
                 </exclusion>
             </exclusions>
         </dependency>
-        <dependency>
-            <groupId>com.sun.jersey</groupId>
-            <artifactId>jersey-core</artifactId>
-            <version>${jersey-core.version}</version>
-            <scope>compile</scope>
-            <exclusions>
-                <exclusion>
-                    <groupId>javax.ws.rs</groupId>
-                    <artifactId>jsr311-api</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>com.sun.jersey</groupId>
-            <artifactId>jersey-json</artifactId>
-            <version>${jersey-bundle.version}</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.codehaus.jackson</groupId>
-                    <artifactId>*</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-        <dependency>
-            <groupId>com.sun.jersey</groupId>
-            <artifactId>jersey-server</artifactId>
-            <version>${jersey-server.version}</version>
-            <scope>compile</scope>
-        </dependency>
         <dependency>
             <groupId>com.sun.xml.bind</groupId>
             <artifactId>jaxb-impl</artifactId>
@@ -425,21 +396,6 @@
             <artifactId>ranger-metrics</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>com.nimbusds</groupId>
-                    <artifactId>nimbus-jose-jwt</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>net.minidev</groupId>
-                    <artifactId>json-smart</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
         <dependency>
             <groupId>org.apache.zookeeper</groupId>
             <artifactId>zookeeper</artifactId>
diff --git 
a/kms/src/main/java/org/apache/ranger/plugin/util/AutoClosableLock.java 
b/kms/src/main/java/org/apache/ranger/plugin/util/AutoClosableLock.java
new file mode 100644
index 000000000..5082bc8c7
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/plugin/util/AutoClosableLock.java
@@ -0,0 +1,116 @@
+/*
+ * 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.plugin.util;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+
+public class AutoClosableLock implements AutoCloseable {
+    private final Lock lock;
+
+    public AutoClosableLock(Lock lock) {
+        this.lock = lock;
+
+        this.lock.lock();
+    }
+
+    @Override
+    public void close() {
+        lock.unlock();
+    }
+
+    public static class AutoClosableTryLock implements AutoCloseable {
+        private final Lock    lock;
+        private final boolean isLocked;
+
+        public AutoClosableTryLock(Lock lock, long timeout, TimeUnit timeUnit) 
{
+            this.lock = lock;
+
+            boolean isLocked = false;
+
+            try {
+                isLocked = this.lock.tryLock(timeout, timeUnit);
+            } catch (InterruptedException excp) {
+                // ignored
+            }
+
+            this.isLocked = isLocked;
+        }
+
+        public boolean isLocked() { return isLocked; }
+
+        @Override
+        public void close() {
+            if (isLocked) {
+                lock.unlock();
+            }
+        }
+    }
+
+    public static class AutoClosableReadLock implements AutoCloseable {
+        private final ReadWriteLock lock;
+
+        public AutoClosableReadLock(ReadWriteLock lock) {
+            this.lock = lock;
+
+            this.lock.readLock().lock();
+        }
+
+        @Override
+        public void close() {
+            lock.readLock().unlock();
+        }
+    }
+
+    public static class AutoClosableWriteLock implements AutoCloseable {
+        private final ReadWriteLock lock;
+
+        public AutoClosableWriteLock(ReadWriteLock lock) {
+            this.lock = lock;
+
+            this.lock.writeLock().lock();
+        }
+
+        @Override
+        public void close() {
+            lock.writeLock().unlock();
+        }
+    }
+
+    public static class AutoClosableTryWriteLock implements AutoCloseable {
+        private final ReadWriteLock lock;
+        private final boolean       isLocked;
+
+        public AutoClosableTryWriteLock(ReadWriteLock lock) {
+            this.lock     = lock;
+            this.isLocked = this.lock.writeLock().tryLock();
+        }
+
+        public boolean isLocked() { return isLocked; }
+
+        @Override
+        public void close() {
+            if (isLocked) {
+                lock.writeLock().unlock();
+            }
+        }
+    }
+}
diff --git a/kms/src/main/java/org/apache/ranger/plugin/util/JsonUtilsV2.java 
b/kms/src/main/java/org/apache/ranger/plugin/util/JsonUtilsV2.java
new file mode 100644
index 000000000..bee8c5ac7
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/plugin/util/JsonUtilsV2.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.plugin.util;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.io.Reader;
+import java.io.Serializable;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class JsonUtilsV2 {
+
+    static private final ThreadLocal<ObjectMapper> mapper = new 
ThreadLocal<ObjectMapper>() {
+        @Override
+        protected ObjectMapper initialValue() {
+            return new ObjectMapper();
+        }
+    };
+
+    static public ObjectMapper getMapper() {
+        return mapper.get();
+    }
+
+    static public Map<String, String> jsonToMap(String jsonStr) throws 
Exception {
+        final Map<String, String> ret;
+
+        if (jsonStr == null || jsonStr.isEmpty()) {
+            ret = new HashMap<>();
+        } else {
+            ret = getMapper().readValue(jsonStr, new TypeReference<Map<String, 
String>>() {});
+        }
+
+        return ret;
+    }
+
+    static public String mapToJson(Map<?, ?> map) throws Exception {
+        return getMapper().writeValueAsString(map);
+    }
+
+    static public String listToJson(List<?> list) throws Exception {
+        return getMapper().writeValueAsString(list);
+    }
+
+    static public String objToJson(Serializable obj) throws Exception {
+        return getMapper().writeValueAsString(obj);
+    }
+
+    static public <T> T jsonToObj(String json, Class<T> tClass) throws 
Exception {
+        return getMapper().readValue(json, tClass);
+    }
+
+    static public <T> T jsonToObj(String json, TypeReference<T> typeRef) 
throws Exception {
+        return getMapper().readValue(json, typeRef);
+    }
+
+
+    static public void writeValue(Writer writer, Object obj) throws Exception {
+        getMapper().writeValue(writer, obj);
+    }
+
+    static public <T> T readValue(Reader reader, Class<T> tClass) throws 
Exception {
+        return getMapper().readValue(reader, tClass);
+    }
+
+    static public String nonSerializableObjToJson(Object obj) throws Exception 
{
+        return getMapper().writeValueAsString(obj);
+    }
+}
diff --git a/kms/src/main/java/org/apache/ranger/plugin/util/XMLUtils.java 
b/kms/src/main/java/org/apache/ranger/plugin/util/XMLUtils.java
new file mode 100644
index 000000000..02ad7d616
--- /dev/null
+++ b/kms/src/main/java/org/apache/ranger/plugin/util/XMLUtils.java
@@ -0,0 +1,142 @@
+/*
+ * 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.plugin.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.util.Map;
+
+import javax.xml.XMLConstants;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+public class XMLUtils {
+
+       private static final Logger LOG = 
LoggerFactory.getLogger(XMLUtils.class);
+
+       private static final String XMLCONFIG_PROPERTY_TAGNAME = "property";
+       private static final String XMLCONFIG_NAME_TAGNAME = "name";
+       private static final String XMLCONFIG_VALUE_TAGNAME = "value";
+
+       public static void loadConfig(String configFileName, Map<Object, 
Object> properties) {
+               try (InputStream input = getFileInputStream(configFileName)) {
+                       loadConfig(input, properties);
+               } catch (Exception e) {
+                       LOG.error("Error loading : {}", configFileName, e);
+               }
+       }
+
+       public static void loadConfig(InputStream input, Map<Object, Object> 
properties) {
+               try {
+                       DocumentBuilderFactory xmlDocumentBuilderFactory = 
DocumentBuilderFactory.newInstance();
+                       
xmlDocumentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, 
true);
+                       
xmlDocumentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities";,
 false);
+            
xmlDocumentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities";,
 false);
+                       xmlDocumentBuilderFactory.setIgnoringComments(true);
+                       xmlDocumentBuilderFactory.setNamespaceAware(true);
+
+                       DocumentBuilder xmlDocumentBuilder = 
xmlDocumentBuilderFactory.newDocumentBuilder();
+                       Document xmlDocument = xmlDocumentBuilder.parse(input);
+                       xmlDocument.getDocumentElement().normalize();
+
+                       NodeList nList = 
xmlDocument.getElementsByTagName(XMLCONFIG_PROPERTY_TAGNAME);
+
+                       for (int temp = 0; temp < nList.getLength(); temp++) {
+
+                               Node nNode = nList.item(temp);
+
+                               if (nNode.getNodeType() == Node.ELEMENT_NODE) {
+
+                                       Element eElement = (Element) nNode;
+
+                                       String propertyName = "";
+                                       String propertyValue = "";
+                                       if 
(eElement.getElementsByTagName(XMLCONFIG_NAME_TAGNAME).item(0) != null) {
+                                               propertyName = 
eElement.getElementsByTagName(XMLCONFIG_NAME_TAGNAME)
+                                                               
.item(0).getTextContent().trim();
+                                       }
+                                       if 
(eElement.getElementsByTagName(XMLCONFIG_VALUE_TAGNAME).item(0) != null) {
+                                               propertyValue = 
eElement.getElementsByTagName(XMLCONFIG_VALUE_TAGNAME)
+                                                               
.item(0).getTextContent().trim();
+                                       }
+
+                                       if (properties.get(propertyName) != 
null) {
+                                               properties.remove(propertyName);
+                                       }
+
+                                       properties.put(propertyName, 
propertyValue);
+
+                               }
+                       }
+
+               } catch (Exception e) {
+                       LOG.error("Error loading : ", e);
+               }
+       }
+
+       private static InputStream getFileInputStream(String path) throws 
FileNotFoundException {
+
+               InputStream ret = null;
+
+               // Guard against path traversal attacks
+               String sanitizedPath = new File(path).getName();
+               if ("".equals(sanitizedPath)) {
+                       return null;
+               }
+               File f = new File(sanitizedPath);
+
+               if (f.exists()) {
+                       ret = new FileInputStream(f);
+               } else {
+                       ret = XMLUtils.class.getResourceAsStream(path);
+
+                       if (ret == null) {
+                               if (! path.startsWith("/")) {
+                                       ret = 
XMLUtils.class.getResourceAsStream("/" + path);
+                               }
+                       }
+
+                       if (ret == null) {
+                               ret = 
ClassLoader.getSystemClassLoader().getResourceAsStream(path);
+                               if (ret == null) {
+                                       if (! path.startsWith("/")) {
+                                               ret = 
ClassLoader.getSystemResourceAsStream("/" + path);
+                                       }
+                               }
+                       }
+               }
+
+               if (ret == null) {
+                       throw new FileNotFoundException(path + " is not found");
+               }
+
+               return ret;
+       }
+
+}
diff --git a/ranger-atlas-plugin-shim/pom.xml b/ranger-atlas-plugin-shim/pom.xml
index 1dd14eebb..059697a7a 100644
--- a/ranger-atlas-plugin-shim/pom.xml
+++ b/ranger-atlas-plugin-shim/pom.xml
@@ -56,11 +56,6 @@
             <artifactId>ranger-plugin-classloader</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
diff --git a/ranger-hbase-plugin-shim/pom.xml b/ranger-hbase-plugin-shim/pom.xml
index 48b8950ea..0eee088c1 100644
--- a/ranger-hbase-plugin-shim/pom.xml
+++ b/ranger-hbase-plugin-shim/pom.xml
@@ -83,11 +83,6 @@
             <artifactId>ranger-plugin-classloader</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
         <dependency>
             <groupId>org.glassfish</groupId>
             <artifactId>javax.el</artifactId>
diff --git a/ranger-hdfs-plugin-shim/pom.xml b/ranger-hdfs-plugin-shim/pom.xml
index 267954294..5993c224f 100644
--- a/ranger-hdfs-plugin-shim/pom.xml
+++ b/ranger-hdfs-plugin-shim/pom.xml
@@ -59,10 +59,5 @@
             <artifactId>ranger-plugin-classloader</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
     </dependencies>
 </project>
diff --git a/ranger-hive-plugin-shim/pom.xml b/ranger-hive-plugin-shim/pom.xml
index 13e589924..18ff91586 100644
--- a/ranger-hive-plugin-shim/pom.xml
+++ b/ranger-hive-plugin-shim/pom.xml
@@ -79,11 +79,6 @@
             <artifactId>ranger-plugin-classloader</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
         <dependency>
             <groupId>org.glassfish</groupId>
             <artifactId>javax.el</artifactId>
diff --git a/ranger-kafka-plugin-shim/pom.xml b/ranger-kafka-plugin-shim/pom.xml
index 6a6669715..3b6be2d0d 100644
--- a/ranger-kafka-plugin-shim/pom.xml
+++ b/ranger-kafka-plugin-shim/pom.xml
@@ -46,10 +46,5 @@
             <artifactId>ranger-plugin-classloader</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
     </dependencies>
 </project>
diff --git a/ranger-kms-plugin-shim/pom.xml b/ranger-kms-plugin-shim/pom.xml
index ce0282d17..c330c6ce1 100644
--- a/ranger-kms-plugin-shim/pom.xml
+++ b/ranger-kms-plugin-shim/pom.xml
@@ -46,10 +46,5 @@
             <artifactId>ranger-plugin-classloader</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
     </dependencies>
 </project>
diff --git a/ranger-knox-plugin-shim/pom.xml b/ranger-knox-plugin-shim/pom.xml
index 01d0959d9..6d46bdd4a 100644
--- a/ranger-knox-plugin-shim/pom.xml
+++ b/ranger-knox-plugin-shim/pom.xml
@@ -59,11 +59,6 @@
             <artifactId>ranger-plugin-classloader</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
 
         <!-- Test -->
         <dependency>
diff --git a/ranger-kylin-plugin-shim/pom.xml b/ranger-kylin-plugin-shim/pom.xml
index 81bafbadd..42de5c815 100644
--- a/ranger-kylin-plugin-shim/pom.xml
+++ b/ranger-kylin-plugin-shim/pom.xml
@@ -41,11 +41,6 @@
             <artifactId>ranger-plugin-classloader</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
         <dependency>
             <groupId>org.apache.kylin</groupId>
             <artifactId>kylin-server-base</artifactId>
diff --git a/ranger-ozone-plugin-shim/pom.xml b/ranger-ozone-plugin-shim/pom.xml
index f3b030af6..522b67562 100644
--- a/ranger-ozone-plugin-shim/pom.xml
+++ b/ranger-ozone-plugin-shim/pom.xml
@@ -56,10 +56,5 @@
             <artifactId>ranger-plugin-classloader</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
     </dependencies>
 </project>
diff --git a/ranger-presto-plugin-shim/pom.xml 
b/ranger-presto-plugin-shim/pom.xml
index 2b5f3f90b..3c517dd6d 100644
--- a/ranger-presto-plugin-shim/pom.xml
+++ b/ranger-presto-plugin-shim/pom.xml
@@ -131,12 +131,6 @@
             <artifactId>ranger-plugin-classloader</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
         <dependency>
             <groupId>org.apache.zookeeper</groupId>
             <artifactId>zookeeper</artifactId>
diff --git a/ranger-solr-plugin-shim/pom.xml b/ranger-solr-plugin-shim/pom.xml
index 4a6799771..e5c01a3b3 100644
--- a/ranger-solr-plugin-shim/pom.xml
+++ b/ranger-solr-plugin-shim/pom.xml
@@ -41,11 +41,6 @@
             <artifactId>ranger-plugin-classloader</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
         <dependency>
             <groupId>org.apache.solr</groupId>
             <artifactId>solr-core</artifactId>
diff --git a/ranger-sqoop-plugin-shim/pom.xml b/ranger-sqoop-plugin-shim/pom.xml
index 7271c1c20..db3b61537 100644
--- a/ranger-sqoop-plugin-shim/pom.xml
+++ b/ranger-sqoop-plugin-shim/pom.xml
@@ -41,11 +41,6 @@
             <artifactId>ranger-plugin-classloader</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
         <dependency>
             <groupId>org.apache.sqoop</groupId>
             <artifactId>sqoop-core</artifactId>
diff --git a/ranger-storm-plugin-shim/pom.xml b/ranger-storm-plugin-shim/pom.xml
index 1fd37f225..71a68fff1 100644
--- a/ranger-storm-plugin-shim/pom.xml
+++ b/ranger-storm-plugin-shim/pom.xml
@@ -41,11 +41,6 @@
             <artifactId>ranger-plugin-classloader</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
         <dependency>
             <groupId>org.apache.storm</groupId>
             <artifactId>storm-core</artifactId>
diff --git a/ranger-yarn-plugin-shim/pom.xml b/ranger-yarn-plugin-shim/pom.xml
index 030e41c27..e6aa84579 100644
--- a/ranger-yarn-plugin-shim/pom.xml
+++ b/ranger-yarn-plugin-shim/pom.xml
@@ -56,10 +56,5 @@
             <artifactId>ranger-plugin-classloader</artifactId>
             <version>${project.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-plugins-common</artifactId>
-            <version>${project.version}</version>
-        </dependency>
     </dependencies>
 </project>


Reply via email to