You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2020/03/17 17:00:28 UTC

[ranger] branch master updated: RANGER-2748: Schema Registry - service-def and resource-lookup implementation

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 6d6682c  RANGER-2748: Schema Registry - service-def and resource-lookup implementation
6d6682c is described below

commit 6d6682cbf12c04f76545b9e2451c6ba3de06ac74
Author: vomoshkovskyi <vo...@cloudera.com>
AuthorDate: Fri Jan 17 11:58:47 2020 +0200

    RANGER-2748: Schema Registry - service-def and resource-lookup implementation
    
    Signed-off-by: Madhan Neethiraj <ma...@apache.org>
---
 .../plugin/store/EmbeddedServiceDefsUtil.java      |   8 +
 .../ranger-servicedef-schema-registry.json         | 259 ++++++++++++++++++
 distro/pom.xml                                     |  31 +++
 .../src/main/assembly/plugin-schema-registry.xml   |  39 +++
 plugin-schema-registry/.gitignore                  |   3 +
 plugin-schema-registry/pom.xml                     | 245 +++++++++++++++++
 .../registry/RangerServiceSchemaRegistry.java      |  88 ++++++
 .../registry/client/AutocompletionAgent.java       | 144 ++++++++++
 .../registry/client/SchemaRegistryResourceMgr.java | 134 ++++++++++
 .../connection/DefaultSchemaRegistryClient.java    | 294 +++++++++++++++++++++
 .../client/connection/ISchemaRegistryClient.java   |  28 ++
 .../client/connection/util/SecurityUtils.java      | 228 ++++++++++++++++
 .../registry/client/AutocompletionAgentTest.java   | 194 ++++++++++++++
 .../client/SchemaRegistryResourceMgrTest.java      | 108 ++++++++
 .../DefaultSchemaRegistryClientTest.java           | 190 +++++++++++++
 .../client/connection/util/SecurityUtilsTest.java  | 121 +++++++++
 .../client/util/AcceptAllHostnameVerifier.java     |  28 ++
 .../DefaultSchemaRegistryClientForTesting.java     |  46 ++++
 .../client/util/TestAutocompletionAgent.java       |  59 +++++
 .../src/test/resources/keystore.jks                | Bin 0 -> 2272 bytes
 .../src/test/resources/schema-text3.avcs           |   9 +
 .../test/resources/ssl-schema-registry-client.yaml |  27 ++
 .../src/test/resources/ssl-schema-registry.yaml    |  79 ++++++
 .../src/test/resources/truststore.jks              | Bin 0 -> 982 bytes
 pom.xml                                            |   5 +
 25 files changed, 2367 insertions(+)

diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java
index 882ca2f..072c803 100755
--- a/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java
@@ -61,6 +61,7 @@ public class EmbeddedServiceDefsUtil {
 	public static final String EMBEDDED_SERVICEDEF_YARN_NAME  = "yarn";
 	public static final String EMBEDDED_SERVICEDEF_KAFKA_NAME = "kafka";
 	public static final String EMBEDDED_SERVICEDEF_SOLR_NAME  = "solr";
+	public static final String EMBEDDED_SERVICEDEF_SCHEMA_REGISTRY_NAME  = "schema-registry";
 	public static final String EMBEDDED_SERVICEDEF_NIFI_NAME  = "nifi";
 	public static final String EMBEDDED_SERVICEDEF_NIFI_REGISTRY_NAME  = "nifi-registry";
 	public static final String EMBEDDED_SERVICEDEF_ATLAS_NAME  = "atlas";
@@ -84,6 +85,7 @@ public class EmbeddedServiceDefsUtil {
 	public static final String YARN_IMPL_CLASS_NAME  = "org.apache.ranger.services.yarn.RangerServiceYarn";
 	public static final String KAFKA_IMPL_CLASS_NAME = "org.apache.ranger.services.kafka.RangerServiceKafka";
 	public static final String SOLR_IMPL_CLASS_NAME  = "org.apache.ranger.services.solr.RangerServiceSolr";
+	public static final String SCHEMA_REGISTRY_IMPL_CLASS_NAME  = "org.apache.ranger.services.schemaregistry.RangerServiceSchemaRegistry";
 	public static final String NIFI_IMPL_CLASS_NAME  = "org.apache.ranger.services.nifi.RangerServiceNiFi";
 	public static final String ATLAS_IMPL_CLASS_NAME  = "org.apache.ranger.services.atlas.RangerServiceAtlas";
 	public static final String PRESTO_IMPL_CLASS_NAME  = "org.apache.ranger.services.presto.RangerServicePresto";
@@ -102,6 +104,7 @@ public class EmbeddedServiceDefsUtil {
 	private RangerServiceDef yarnServiceDef;
 	private RangerServiceDef kafkaServiceDef;
 	private RangerServiceDef solrServiceDef;
+	private RangerServiceDef schemaRegistryServiceDef;
 	private RangerServiceDef nifiServiceDef;
 	private RangerServiceDef nifiRegistryServiceDef;
 	private RangerServiceDef atlasServiceDef;
@@ -149,6 +152,7 @@ public class EmbeddedServiceDefsUtil {
 			yarnServiceDef  = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_YARN_NAME);
 			kafkaServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_KAFKA_NAME);
 			solrServiceDef  = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_SOLR_NAME);
+			schemaRegistryServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_SCHEMA_REGISTRY_NAME);
 			nifiServiceDef  = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_NIFI_NAME);
 			nifiRegistryServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_NIFI_REGISTRY_NAME);
 			atlasServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_ATLAS_NAME);
@@ -208,6 +212,10 @@ public class EmbeddedServiceDefsUtil {
 		return getId(solrServiceDef);
 	}
 
+	public long getSchemaRegistryServiceDefId() {
+		return getId(schemaRegistryServiceDef);
+	}
+
 	public long getNiFiServiceDefId() {
 		return getId(nifiServiceDef);
 	}
diff --git a/agents-common/src/main/resources/service-defs/ranger-servicedef-schema-registry.json b/agents-common/src/main/resources/service-defs/ranger-servicedef-schema-registry.json
new file mode 100644
index 0000000..3997cc2
--- /dev/null
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-schema-registry.json
@@ -0,0 +1,259 @@
+{
+  "name": "schema-registry",
+  "implClass": "org.apache.ranger.services.schema.registry.RangerServiceSchemaRegistry",
+  "label": "Schema Registry",
+  "description": "Schema Registry",
+  "resources":
+  [
+
+    {
+      "itemId": 0,
+      "name": "registry-service",
+      "type": "string",
+      "level": 10,
+      "parent": "",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {
+        "wildCard":true,
+        "ignoreCase":true
+      },
+      "validationRegEx": "^\\*$",
+      "validationMessage": "",
+      "uiHint":"",
+      "label": "Schema Registry Service",
+      "description": "Schema Registry Service"
+    },
+
+    {
+      "itemId": 1,
+      "name": "schema-group",
+      "type": "string",
+      "level": 10,
+      "parent": "",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {
+        "wildCard":true,
+        "ignoreCase":true
+      },
+      "validationRegEx":"",
+      "validationMessage": "",
+      "uiHint":"",
+      "label": "Schema Group",
+      "description": "Schema Group"
+    },
+
+    {
+      "itemId": 22,
+      "name": "schema-metadata",
+      "type": "string",
+      "level": 20,
+      "parent": "schema-group",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {
+        "wildCard":true,
+        "ignoreCase":true
+      },
+      "validationRegEx":"",
+      "validationMessage": "",
+      "uiHint":"",
+      "label": "Schema Name",
+      "description": "Schema Name",
+      "isValidLeaf": "true"
+    },
+
+
+    {
+      "itemId": 32,
+      "name": "schema-branch",
+      "type": "string",
+      "level": 30,
+      "parent": "schema-metadata",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {
+        "wildCard":true,
+        "ignoreCase":true
+      },
+      "validationRegEx":"",
+      "validationMessage": "",
+      "uiHint":"",
+      "label": "Schema Branch",
+      "description": "Schema Branch",
+      "isValidLeaf": "true"
+    },
+
+    {
+      "itemId": 42,
+      "name": "schema-version",
+      "type": "string",
+      "level": 40,
+      "parent": "schema-branch",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {
+        "wildCard":true,
+        "ignoreCase":true
+      },
+      "validationRegEx": "^\\*$",
+      "validationMessage": "",
+      "uiHint":"",
+      "label": "Schema Version",
+      "description": "Schema Version"
+    },
+
+    {
+      "itemId": 5,
+      "name": "serde",
+      "type": "string",
+      "level": 10,
+      "parent": "",
+      "mandatory": true,
+      "lookupSupported": true,
+      "recursiveSupported": false,
+      "excludesSupported": true,
+      "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+      "matcherOptions": {
+        "wildCard":true,
+        "ignoreCase":true
+      },
+      "validationRegEx": "^\\*$",
+      "validationMessage": "",
+      "uiHint":"",
+      "label": "Serializer/Deserializer",
+      "description": "Serializer/Deserializer"
+    }
+
+  ],
+
+  "accessTypes":
+  [
+    {
+      "itemId": 1,
+      "name": "create",
+      "label": "Create"
+    },
+
+    {
+      "itemId": 2,
+      "name": "read",
+      "label": "Read"
+    },
+
+    {
+      "itemId": 3,
+      "name": "update",
+      "label": "Update"
+    },
+
+    {
+      "itemId": 4,
+      "name": "delete",
+      "label": "Delete"
+    }
+  ],
+
+  "configs":
+  [
+    {
+      "itemId": 1,
+      "name": "schema.registry.url",
+      "type": "string",
+      "mandatory": true,
+      "defaultValue": "",
+      "validationRegEx":"",
+      "validationMessage": "",
+      "uiHint":"",
+      "label": "Schema Registry URL"
+    },
+
+    {
+      "itemId": 2,
+      "name": "schema-registry.authentication",
+      "type": "enum",
+      "subType": "authType",
+      "mandatory": true,
+      "validationRegEx":"",
+      "validationMessage": "",
+      "uiHint":"",
+      "label": "Authentication Type",
+      "defaultValue": "KERBEROS"
+    },
+
+    {
+      "itemId": 3,
+      "name": "commonNameForCertificate",
+      "type": "string",
+      "mandatory": false,
+      "validationRegEx":"",
+      "validationMessage": "",
+      "uiHint":"",
+      "label": "Ranger Plugin SSL CName"
+    }
+
+  ],
+
+  "enums":
+  [
+    {
+      "itemId": 1,
+      "name": "authType",
+      "elements":
+      [
+        {
+          "itemId": 1,
+          "name": "NONE",
+          "label": "None"
+        },
+        {
+          "itemId": 2,
+          "name": "KERBEROS",
+          "label": "Kerberos"
+        }
+      ],
+
+      "defaultIndex": 0
+    }
+  ],
+
+  "contextEnrichers":
+  [
+
+  ],
+
+  "policyConditions":
+  [
+
+    {
+      "itemId":4,
+      "name":"ip-range",
+      "evaluator":"org.apache.ranger.plugin.conditionevaluator.RangerIpMatcher",
+      "evaluatorOptions":{
+
+      },
+      "validationRegEx":"",
+      "validationMessage":"",
+      "uiHint":"",
+      "label":"IP Address Range",
+      "description":"IP Address Range"
+    }
+
+  ]
+}
diff --git a/distro/pom.xml b/distro/pom.xml
index 49faefc..6c4fdae 100644
--- a/distro/pom.xml
+++ b/distro/pom.xml
@@ -73,6 +73,7 @@
                                         <descriptor>src/main/assembly/plugin-sqoop.xml</descriptor>
                                         <descriptor>src/main/assembly/plugin-kylin.xml</descriptor>
                                         <descriptor>src/main/assembly/plugin-elasticsearch.xml</descriptor>
+                                        <descriptor>src/main/assembly/plugin-schema-registry.xml</descriptor>
                                         <descriptor>src/main/assembly/plugin-presto.xml</descriptor>
                                     </descriptors>
                                 </configuration>
@@ -553,6 +554,35 @@
             </build>
         </profile>
         <profile>
+            <id>ranger-schema-registry-plugin</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <version>${assembly.plugin.version}</version>
+                        <configuration>
+                            <finalName>ranger-${project.version}</finalName>
+                            <outputDirectory>../target</outputDirectory>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                                <phase>package</phase>
+                                <configuration>
+                                    <skipAssembly>false</skipAssembly>
+                                    <descriptors>
+                                        <descriptor>src/main/assembly/plugin-schema-registry.xml</descriptor>
+                                    </descriptors>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
             <id>linux</id>
             <activation>
                 <os>
@@ -598,6 +628,7 @@
                                         <descriptor>src/main/assembly/plugin-sqoop.xml</descriptor>
                                         <descriptor>src/main/assembly/plugin-kylin.xml</descriptor>
                                         <descriptor>src/main/assembly/plugin-elasticsearch.xml</descriptor>
+                                        <descriptor>src/main/assembly/plugin-schema-registry.xml</descriptor>
                                         <descriptor>src/main/assembly/plugin-presto.xml</descriptor>
                                     </descriptors>
                                 </configuration>
diff --git a/distro/src/main/assembly/plugin-schema-registry.xml b/distro/src/main/assembly/plugin-schema-registry.xml
new file mode 100644
index 0000000..03f01ae
--- /dev/null
+++ b/distro/src/main/assembly/plugin-schema-registry.xml
@@ -0,0 +1,39 @@
+<!--
+  Copyright 2016-2019 Cloudera, Inc.
+
+   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.
+-->
+
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+    <id>schema-registry-plugin</id>
+    <formats>
+        <format>jar</format>
+    </formats>
+    <includeBaseDirectory>false</includeBaseDirectory>
+
+    <!-- put deps in the lib folder -->
+    <dependencySets>
+        <dependencySet>
+            <useProjectArtifact>true</useProjectArtifact>
+            <outputDirectory>/</outputDirectory>
+            <scope>runtime</scope>
+            <unpack>true</unpack>
+            <excludes>
+                <exclude>
+                    org.slf4j:*
+                </exclude>
+            </excludes>
+        </dependencySet>
+    </dependencySets>
+</assembly>
diff --git a/plugin-schema-registry/.gitignore b/plugin-schema-registry/.gitignore
new file mode 100644
index 0000000..02f68bb
--- /dev/null
+++ b/plugin-schema-registry/.gitignore
@@ -0,0 +1,3 @@
+/target/
+/bin/
+.settings/
diff --git a/plugin-schema-registry/pom.xml b/plugin-schema-registry/pom.xml
new file mode 100644
index 0000000..6bd2d97
--- /dev/null
+++ b/plugin-schema-registry/pom.xml
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>ranger-schema-registry-plugin</artifactId>
+    <name>SchemaRegistry Security Plugin</name>
+    <description>SchemaRegistry Security Plugin</description>
+    <packaging>jar</packaging>
+
+    <parent>
+        <groupId>org.apache.ranger</groupId>
+        <artifactId>ranger</artifactId>
+        <version>2.1.0-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+
+    <properties>
+        <hadoop.version>3.1.1</hadoop.version>
+        <kafka.version>2.1.0</kafka.version>
+        <kafkaArtifact>kafka_2.11</kafkaArtifact>
+        <jersey.version>2.22.1</jersey.version>
+        <junit.version>4.5</junit.version>
+        <schema.registry.version>0.8.1</schema.registry.version>
+        <jettison.version>1.1</jettison.version>
+        <servlet-api.version>3.0.1</servlet-api.version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.apache.hadoop</groupId>
+                <artifactId>hadoop-hdfs</artifactId>
+                <version>${hadoop.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>log4j</groupId>
+                        <artifactId>log4j</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>com.sun.jersey</groupId>
+                        <artifactId>jersey-core</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>com.sun.jersey</groupId>
+                        <artifactId>jersey-json</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.slf4j</groupId>
+                        <artifactId>slf4j-log4j12</artifactId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.hadoop</groupId>
+                <artifactId>hadoop-client</artifactId>
+                <version>${hadoop.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>log4j</groupId>
+                        <artifactId>log4j</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>com.sun.jersey</groupId>
+                        <artifactId>jersey-core</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>javax.servlet</groupId>
+                        <artifactId>servlet-api</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>log4j</groupId>
+                        <artifactId>log4j</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.slf4j</groupId>
+                        <artifactId>slf4j-log4j12</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>com.sun.jersey</groupId>
+                        <artifactId>jersey-client</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.apache.hadoop</groupId>
+                        <artifactId>hadoop-yarn-api</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.apache.hadoop</groupId>
+                        <artifactId>hadoop-yarn-common</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.apache.hadoop</groupId>
+                        <artifactId>hadoop-mapreduce-client</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.apache.hadoop</groupId>
+                        <artifactId>hadoop-mapreduce-client-app</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.apache.hadoop</groupId>
+                        <artifactId>hadoop-mapreduce-client-core</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.apache.hadoop</groupId>
+                        <artifactId>hadoop-mapreduce-client-jobclient</artifactId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.kafka</groupId>
+                <artifactId>${kafkaArtifact}</artifactId>
+                <version>${kafka.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>org.apache.zookeeper</groupId>
+                        <artifactId>zookeeper</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>log4j</groupId>
+                        <artifactId>log4j</artifactId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+            <dependency>
+                <groupId>org.glassfish.jersey.core</groupId>
+                <artifactId>jersey-client</artifactId>
+                <version>${jersey.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.hortonworks.registries</groupId>
+            <artifactId>common-auth</artifactId>
+            <version>${schema.registry.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.hortonworks.registries</groupId>
+            <artifactId>schema-registry-client</artifactId>
+            <version>${schema.registry.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>log4j</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ranger</groupId>
+            <artifactId>ranger-plugins-common</artifactId>
+            <version>${project.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.servlet</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.sun.jersey</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>log4j</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>javax.servlet.jsp</groupId>
+                    <artifactId>jsp-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>javax.ws.rs</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.glassfish.jersey.*</groupId>
+                    <artifactId>*</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.jettison</groupId>
+            <artifactId>jettison</artifactId>
+            <version>${jettison.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.hortonworks.registries</groupId>
+            <artifactId>schema-registry-webservice</artifactId>
+            <version>${schema.registry.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+            <version>${servlet-api.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>**/src/test/resources/**/*.yaml</exclude>
+                        <exclude>**/src/test/resources/**/*.avcs</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/RangerServiceSchemaRegistry.java b/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/RangerServiceSchemaRegistry.java
new file mode 100644
index 0000000..8306b51
--- /dev/null
+++ b/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/RangerServiceSchemaRegistry.java
@@ -0,0 +1,88 @@
+/*
+ * 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.services.schema.registry;
+
+import org.apache.ranger.services.schema.registry.client.AutocompletionAgent;
+import org.apache.ranger.services.schema.registry.client.SchemaRegistryResourceMgr;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.service.RangerBaseService;
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class RangerServiceSchemaRegistry extends RangerBaseService {
+
+    private static final Log LOG = LogFactory.getLog(RangerServiceSchemaRegistry.class);
+
+
+    @Override
+    public void init(RangerServiceDef serviceDef, RangerService service) {
+        super.init(serviceDef, service);
+    }
+
+    @Override
+    public HashMap<String, Object> validateConfig() {
+        HashMap<String, Object> ret = new HashMap<String, Object>();
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> RangerServiceSchemaRegistry.validateConfig(" + serviceName + ")");
+        }
+
+        if (configs != null) {
+            try {
+                AutocompletionAgent autocompletionAgent = new AutocompletionAgent(serviceName, configs);
+                ret = autocompletionAgent.connectionTest();
+            } catch (Exception e) {
+                LOG.error("<== RangerServiceSchemaRegistry.validateConfig Error:" + e);
+                throw e;
+            }
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerServiceSchemaRegistry.validateConfig(" + serviceName + "): ret=" + ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public List<String> lookupResource(ResourceLookupContext context) throws Exception {
+        List<String> ret = new ArrayList<String>();
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> RangerServiceSchemaRegistry.lookupResource(" + serviceName + ")");
+        }
+
+        if (configs != null) {
+            AutocompletionAgent autocompletionAgent = new AutocompletionAgent(serviceName, configs);
+            ret = SchemaRegistryResourceMgr.getSchemaRegistryResources(serviceName, configs, context, autocompletionAgent);
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerServiceSchemaRegistry.lookupResource(" + serviceName + "): ret=" + ret);
+        }
+
+        return ret;
+    }
+
+}
diff --git a/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/client/AutocompletionAgent.java b/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/client/AutocompletionAgent.java
new file mode 100644
index 0000000..3bb107e
--- /dev/null
+++ b/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/client/AutocompletionAgent.java
@@ -0,0 +1,144 @@
+/*
+ * 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.services.schema.registry.client;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.client.BaseClient;
+import org.apache.ranger.services.schema.registry.client.connection.DefaultSchemaRegistryClient;
+import org.apache.ranger.services.schema.registry.client.connection.ISchemaRegistryClient;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * The class that is used to get needed information for auto completion feature.
+ */
+public class AutocompletionAgent {
+    private static final Log LOG = LogFactory.getLog(AutocompletionAgent.class);
+
+    private ISchemaRegistryClient client;
+    private String serviceName;
+
+    private static final String errMessage = "You can still save the repository and start creating "
+            + "policies, but you would not be able to use autocomplete for "
+            + "resource names. Check server logs for more info.";
+
+    private static final String successMsg = "ConnectionTest Successful";
+
+
+    public AutocompletionAgent(String serviceName, Map<String, String> configs) {
+        this(serviceName, new DefaultSchemaRegistryClient(configs));
+    }
+
+    public AutocompletionAgent(String serviceName, ISchemaRegistryClient client) {
+        this.serviceName = serviceName;
+        this.client = client;
+    }
+
+    public HashMap<String, Object> connectionTest() {
+        HashMap<String, Object> responseData = new HashMap<String, Object>();
+
+        try {
+            client.checkConnection();
+            // If it doesn't throw exception, then assume the instance is
+            // reachable
+            BaseClient.generateResponseDataMap(true, successMsg,
+                    successMsg, null, null, responseData);
+            if(LOG.isDebugEnabled()) {
+                LOG.debug("ConnectionTest Successful.");
+            }
+        } catch (Exception e) {
+            LOG.error("Error connecting to SchemaRegistry. schemaRegistryClient=" + this, e);
+            BaseClient.generateResponseDataMap(false, errMessage,
+                    errMessage, null, null, responseData);
+        }
+
+        return responseData;
+    }
+
+    public List<String> getSchemaGroupList(String lookupGroupName, List<String> groupList) {
+        List<String> res = groupList;
+        Collection<String> schemaGroups = client.getSchemaGroups();
+        schemaGroups.forEach(gName -> {
+            if (!res.contains(gName) && gName.contains(lookupGroupName)) {
+                res.add(gName);
+            }
+        });
+
+        return res;
+    }
+
+    public List<String> getSchemaMetadataList(String lookupSchemaMetadataName,
+                                              List<String> schemaGroupList,
+                                              List<String> schemaMetadataList) {
+        List<String> res = schemaMetadataList;
+
+        Collection<String> schemas = client.getSchemaNames(schemaGroupList);
+        schemas.forEach(sName -> {
+            if (!res.contains(sName) && sName.contains(lookupSchemaMetadataName)) {
+                res.add(sName);
+            }
+        });
+
+        return res;
+    }
+
+    public List<String> getBranchList(String lookupBranchName,
+                                      List<String> groupList,
+                                      List<String> schemaList,
+                                      List<String> branchList) {
+        List<String> res = branchList;
+        List<String> expandedSchemaList = schemaList.stream().flatMap(
+                schemaName -> expandSchemaMetadataNameRegex(groupList, schemaName).stream())
+                .collect(Collectors.toList());
+        expandedSchemaList.forEach(schemaMetadataName -> {
+            Collection<String> branches = client.getSchemaBranches(schemaMetadataName);
+            branches.forEach(bName -> {
+                if (!res.contains(bName) && bName.contains(lookupBranchName)) {
+                    res.add(bName);
+                }
+            });
+        });
+
+        return res;
+    }
+
+    List<String> expandSchemaMetadataNameRegex(List<String> schemaGroupList, String lookupSchemaMetadataName) {
+        List<String> res = new ArrayList<>();
+
+        Collection<String> schemas = client.getSchemaNames(schemaGroupList);
+        schemas.forEach(sName -> {
+            if (sName.matches(lookupSchemaMetadataName)) {
+                res.add(sName);
+            }
+        });
+
+        return res;
+    }
+
+    @Override
+    public String toString() {
+        return "AutocompletionAgent [serviceName=" + serviceName + "]";
+    }
+
+}
diff --git a/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/client/SchemaRegistryResourceMgr.java b/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/client/SchemaRegistryResourceMgr.java
new file mode 100644
index 0000000..3cc1199
--- /dev/null
+++ b/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/client/SchemaRegistryResourceMgr.java
@@ -0,0 +1,134 @@
+/*
+ * 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.services.schema.registry.client;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+import org.apache.ranger.plugin.util.TimedEventUtil;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+public class SchemaRegistryResourceMgr {
+
+    private static final Log LOG = LogFactory.getLog(SchemaRegistryResourceMgr.class);
+
+    private static final String REGISTRY_SERVICE = "registry-service";
+    private static final String SERDE = "serde";
+    private static final String SCHEMA_GROUP = "schema-group";
+    private static final String SCHEMA_METADATA = "schema-metadata";
+    private static final String SCHEMA_BRANCH = "schema-branch";
+    private static final String SCHEMA_VERSION = "schema-version";
+
+    private static final List<String> asteriskList = Collections.singletonList("*");
+
+    private static final int LOOKUP_TIMEOUT_SEC = 5;
+
+
+    public static List<String> getSchemaRegistryResources(String serviceName,
+                                                          Map<String, String> configs,
+                                                          ResourceLookupContext context,
+                                                          AutocompletionAgent registryClient) throws Exception {
+
+        String userInput = context.getUserInput();
+        String resource = context.getResourceName();
+        Map<String, List<String>> resourceMap = context.getResources();
+        List<String> resultList = null;
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> SchemaRegistryResourceMgr.getSchemaRegistryResources()  UserInput: \"" + userInput + "\" resource : " + resource + " resourceMap: " + resourceMap);
+        }
+
+        if (userInput != null
+                && !userInput.isEmpty()
+                && serviceName != null
+                && resource != null
+                && resourceMap != null
+                && !resourceMap.isEmpty()) {
+            if (registryClient != null) {
+                Callable<List<String>> callableObj = null;
+                try {
+                    switch (resource.trim().toLowerCase()) {
+                        case SCHEMA_GROUP: {
+                            List<String> schemaGroupList = resourceMap.get(SCHEMA_GROUP);
+                            // get the SchemaGroupList for given Input
+                            final String finalSchemaGroupName = userInput;
+                            callableObj = ()
+                                    -> registryClient.getSchemaGroupList(finalSchemaGroupName, schemaGroupList);
+                            break;
+                        }
+                        case SCHEMA_METADATA: {
+                            List<String> schemaGroupList = resourceMap.get(SCHEMA_GROUP);
+                            List<String> schemaMeatadataList = resourceMap.get(SCHEMA_METADATA);
+                            // get the SchemaMetadataList for the given Input
+                            final String finalSchemaName = userInput;
+                            callableObj = ()
+                                    -> registryClient.getSchemaMetadataList(finalSchemaName,
+                                    schemaGroupList,
+                                    schemaMeatadataList);
+                            break;
+                        }
+                        case SCHEMA_BRANCH: {
+                            List<String> schemaGroupList = resourceMap.get(SCHEMA_GROUP);
+                            List<String> schemaMeatadataList = resourceMap.get(SCHEMA_METADATA);
+                            List<String> branchList = resourceMap.get(SCHEMA_BRANCH);
+                            // get the SchemaBranchList for given Input
+                            final String finalBranchName = userInput;
+                            callableObj = ()
+                                    -> registryClient.getBranchList(finalBranchName,
+                                    schemaGroupList,
+                                    schemaMeatadataList,
+                                    branchList);
+                            break;
+                        }
+                        case SCHEMA_VERSION: case SERDE: case REGISTRY_SERVICE: {
+                            return asteriskList;
+                        }
+                        default:
+                            break;
+                    }
+                } catch (Exception e) {
+                    LOG.error("Unable to get Schema Registry resources.", e);
+                    throw e;
+                }
+                if (callableObj != null) {
+                    synchronized (registryClient) {
+                        resultList = TimedEventUtil.timedTask(callableObj, LOOKUP_TIMEOUT_SEC,
+                                TimeUnit.SECONDS);
+                    }
+                } else {
+                    LOG.error("Could not initiate at timedTask");
+                }
+            }
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== SchemaRegistryResourceMgr.getSchemaRegistryResources() UserInput: "
+                    + userInput
+                    + " configs: " + configs
+                    + "Result :" + resultList );
+
+        }
+
+        return resultList;
+    }
+}
diff --git a/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/client/connection/DefaultSchemaRegistryClient.java b/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/client/connection/DefaultSchemaRegistryClient.java
new file mode 100644
index 0000000..3a46436
--- /dev/null
+++ b/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/client/connection/DefaultSchemaRegistryClient.java
@@ -0,0 +1,294 @@
+/*
+ * 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.services.schema.registry.client.connection;
+
+import com.hortonworks.registries.auth.Login;
+import com.hortonworks.registries.schemaregistry.client.LoadBalancedFailoverUrlSelector;
+import com.hortonworks.registries.schemaregistry.client.UrlSelector;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.services.schema.registry.client.connection.util.SecurityUtils;
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONObject;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.JerseyClientBuilder;
+
+import javax.net.ssl.SSLContext;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.hortonworks.registries.schemaregistry.client.SchemaRegistryClient.Configuration;
+
+import static com.hortonworks.registries.schemaregistry.client.SchemaRegistryClient.Configuration.DEFAULT_CONNECTION_TIMEOUT;
+import static com.hortonworks.registries.schemaregistry.client.SchemaRegistryClient.Configuration.DEFAULT_READ_TIMEOUT;
+
+
+public class DefaultSchemaRegistryClient implements ISchemaRegistryClient {
+
+    private static final Log LOG = LogFactory.getLog(DefaultSchemaRegistryClient.class);
+
+    private static final String SCHEMA_REGISTRY_PATH = "/api/v1/schemaregistry";
+    private static final String SCHEMAS_PATH = SCHEMA_REGISTRY_PATH + "/schemas/";
+    private static final String SCHEMA_REGISTRY_VERSION_PATH = SCHEMA_REGISTRY_PATH + "/version";
+    private static final String SSL_ALGORITHM = "TLS";
+    private final javax.ws.rs.client.Client client;
+    private final Login login;
+    private final UrlSelector urlSelector;
+    private final Map<String, SchemaRegistryTargets> urlWithTargets;
+    private final Configuration configuration;
+
+    public DefaultSchemaRegistryClient(Map<String, ?> conf) {
+        configuration = new Configuration(conf);
+        login = SecurityUtils.initializeSecurityContext(conf);
+        ClientConfig config = createClientConfig(conf);
+        final boolean SSLEnabled = SecurityUtils.isHttpsConnection(conf);
+        ClientBuilder clientBuilder = JerseyClientBuilder.newBuilder()
+                .withConfig(config)
+                .property(ClientProperties.FOLLOW_REDIRECTS, Boolean.TRUE);
+        if (SSLEnabled) {
+            SSLContext ctx;
+            try {
+                ctx = SecurityUtils.createSSLContext(conf, SSL_ALGORITHM);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+            clientBuilder.sslContext(ctx);
+        }
+        client = clientBuilder.build();
+
+        // get list of urls and create given or default UrlSelector.
+        urlSelector = createUrlSelector();
+        urlWithTargets = new ConcurrentHashMap<>();
+    }
+
+    private ClientConfig createClientConfig(Map<String, ?> conf) {
+        ClientConfig config = new ClientConfig();
+        config.property(ClientProperties.CONNECT_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT);
+        config.property(ClientProperties.READ_TIMEOUT, DEFAULT_READ_TIMEOUT);
+        config.property(ClientProperties.FOLLOW_REDIRECTS, true);
+        for (Map.Entry<String, ?> entry : conf.entrySet()) {
+            config.property(entry.getKey(), entry.getValue());
+        }
+        return config;
+    }
+
+    private UrlSelector createUrlSelector() {
+        UrlSelector urlSelector = null;
+        String rootCatalogURL = configuration.getValue(Configuration.SCHEMA_REGISTRY_URL.name());
+        String urlSelectorClass = configuration.getValue(Configuration.URL_SELECTOR_CLASS.name());
+        if (urlSelectorClass == null) {
+            urlSelector = new LoadBalancedFailoverUrlSelector(rootCatalogURL);
+        } else {
+            try {
+                urlSelector = (UrlSelector) Class.forName(urlSelectorClass)
+                        .getConstructor(String.class)
+                        .newInstance(rootCatalogURL);
+            } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | NoSuchMethodException
+                    | InvocationTargetException e) {
+                throw new RuntimeException(e);
+            }
+        }
+        urlSelector.init(configuration.getConfig());
+
+        return urlSelector;
+    }
+
+    private static class SchemaRegistryTargets {
+        private final WebTarget schemaRegistryVersion;
+        private final WebTarget schemasTarget;
+
+        SchemaRegistryTargets(WebTarget rootResource) {
+            schemaRegistryVersion = rootResource.path(SCHEMA_REGISTRY_VERSION_PATH);
+            schemasTarget = rootResource.path(SCHEMAS_PATH);
+        }
+    }
+
+    private SchemaRegistryTargets currentSchemaRegistryTargets() {
+        String url = urlSelector.select();
+        urlWithTargets.computeIfAbsent(url, s -> new SchemaRegistryTargets(client.target(s)));
+        return urlWithTargets.get(url);
+    }
+
+    private static String encode(String schemaName) {
+        try {
+            return URLEncoder.encode(schemaName, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public List<String> getSchemaGroups() {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("==> DefaultSchemaRegistryClient.getSchemaGroups()");
+        }
+
+        ArrayList<String> res = new ArrayList<>();
+        WebTarget webResource = currentSchemaRegistryTargets().schemasTarget;
+        try {
+            Response response = login.doAction(() ->
+                    webResource.request(MediaType.APPLICATION_JSON_TYPE).get(Response.class));
+
+            if(LOG.isDebugEnabled()) {
+                LOG.debug("DefaultSchemaRegistryClient.getSchemaGroups(): response statusCode = " + response.getStatus());
+            }
+
+            JSONArray mDataList = new JSONObject(response.readEntity(String.class)).getJSONArray("entities");
+            int len = mDataList.length();
+            for(int i = 0; i < len; i++) {
+                JSONObject entity = mDataList.getJSONObject(i);
+                JSONObject schemaMetadata = (JSONObject)entity.get("schemaMetadata");
+                String group = (String) schemaMetadata.get("schemaGroup");
+                res.add(group);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== DefaultSchemaRegistryClient.getSchemaGroups(): "
+                    + res.size()
+                    + " schemaGroups found");
+        }
+
+        return res;
+    }
+
+    @Override
+    public List<String> getSchemaNames(List<String> schemaGroups) {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("==> DefaultSchemaRegistryClient.getSchemaNames( " + schemaGroups + " )");
+        }
+
+        ArrayList<String> res = new ArrayList<>();
+        WebTarget webTarget = currentSchemaRegistryTargets().schemasTarget;
+        try {
+            Response response = login.doAction(() ->
+                    webTarget.request(MediaType.APPLICATION_JSON_TYPE).get(Response.class));
+
+            if(LOG.isDebugEnabled()) {
+                LOG.debug("DefaultSchemaRegistryClient.getSchemaNames(): response statusCode = " + response.getStatus());
+            }
+
+            JSONArray mDataList = new JSONObject(response.readEntity(String.class)).getJSONArray("entities");
+            int len = mDataList.length();
+            for(int i = 0; i < len; i++) {
+                JSONObject entity = mDataList.getJSONObject(i);
+                JSONObject schemaMetadata = (JSONObject)entity.get("schemaMetadata");
+                String group = (String) schemaMetadata.get("schemaGroup");
+                for(String schemaGroup:  schemaGroups) {
+                    if(group.matches(schemaGroup)) {
+                        String name = (String) schemaMetadata.get("name");
+                        res.add(name);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== DefaultSchemaRegistryClient.getSchemaNames( " + schemaGroups + " ): "
+                    + res.size()
+                    + " schemaNames found");
+        }
+
+        return res;
+    }
+
+    @Override
+    public List<String> getSchemaBranches(String schemaMetadataName) {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("==> DefaultSchemaRegistryClient.getSchemaBranches( " + schemaMetadataName + " )");
+        }
+
+        ArrayList<String> res = new ArrayList<>();
+        WebTarget target = currentSchemaRegistryTargets().schemasTarget.path(encode(schemaMetadataName) + "/branches");
+        try {
+            Response response = login.doAction(() ->
+                    target.request(MediaType.APPLICATION_JSON_TYPE).get(Response.class));
+
+            if(LOG.isDebugEnabled()) {
+                LOG.debug("DefaultSchemaRegistryClient.getSchemaBranches(): response statusCode = " + response.getStatus());
+            }
+
+            JSONArray mDataList = new JSONObject(response.readEntity(String.class)).getJSONArray("entities");
+            int len = mDataList.length();
+            for(int i = 0; i < len; i++) {
+                JSONObject entity = mDataList.getJSONObject(i);
+                JSONObject branchInfo = entity;
+                String smName = (String) branchInfo.get("schemaMetadataName");
+                if (smName.matches(schemaMetadataName)) {
+                    String bName = (String) branchInfo.get("name");
+                    res.add(bName);
+                }
+
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== DefaultSchemaRegistryClient.getSchemaBranches( " + schemaMetadataName + " ): "
+                    + res.size()
+                    + " branches found.");
+        }
+
+        return res;
+    }
+
+    @Override
+    public void checkConnection() throws Exception {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("==> DefaultSchemaRegistryClient.checkConnection(): trying to connect to the SR server... ");
+        }
+
+        WebTarget webTarget = currentSchemaRegistryTargets().schemaRegistryVersion;
+        Response responce = login.doAction(() ->
+                webTarget.request(MediaType.APPLICATION_JSON_TYPE).get(Response.class));
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("DefaultSchemaRegistryClient.checkConnection(): response statusCode = " + responce.getStatus());
+        }
+        if(responce.getStatus() != Response.Status.OK.getStatusCode()) {
+            LOG.error("DefaultSchemaRegistryClient.checkConnection(): Connection failed. Response StatusCode = "
+                    + responce.getStatus());
+            throw new Exception("Connection failed. StatusCode = " + responce.getStatus());
+        }
+
+        String respStr = responce.readEntity(String.class);
+        if (!(respStr.contains("version") && respStr.contains("revision"))) {
+            LOG.error("DefaultSchemaRegistryClient.checkConnection(): Connection failed. Bad response body.");
+            throw new Exception("Connection failed. Bad response body.");
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== DefaultSchemaRegistryClient.checkConnection(): connection test successfull ");
+        }
+    }
+
+}
diff --git a/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/client/connection/ISchemaRegistryClient.java b/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/client/connection/ISchemaRegistryClient.java
new file mode 100644
index 0000000..98009ce
--- /dev/null
+++ b/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/client/connection/ISchemaRegistryClient.java
@@ -0,0 +1,28 @@
+/*
+ * 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.services.schema.registry.client.connection;
+
+import java.util.List;
+
+public interface ISchemaRegistryClient {
+    List<String> getSchemaGroups();
+    List<String> getSchemaNames(List<String> schemaGroup);
+    List<String> getSchemaBranches(String schemaMetadataName);
+    void checkConnection() throws Exception;
+}
+
diff --git a/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/client/connection/util/SecurityUtils.java b/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/client/connection/util/SecurityUtils.java
new file mode 100644
index 0000000..13eaf8e
--- /dev/null
+++ b/plugin-schema-registry/src/main/java/org/apache/ranger/services/schema/registry/client/connection/util/SecurityUtils.java
@@ -0,0 +1,228 @@
+/*
+ * 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.services.schema.registry.client.connection.util;
+
+import com.hortonworks.registries.auth.KerberosLogin;
+import com.hortonworks.registries.auth.Login;
+import com.hortonworks.registries.auth.NOOPLogin;
+import com.hortonworks.registries.auth.util.JaasConfiguration;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+import javax.security.auth.login.LoginException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+import static com.hortonworks.registries.schemaregistry.client.SchemaRegistryClient.Configuration.SCHEMA_REGISTRY_URL;
+import static org.apache.ranger.plugin.client.HadoopConfigHolder.HADOOP_SECURITY_AUTHENTICATION_METHOD;
+import static org.apache.ranger.plugin.client.HadoopConfigHolder.RANGER_AUTH_TYPE;
+import static org.apache.ranger.plugin.client.HadoopConfigHolder.RANGER_LOOKUP_KEYTAB;
+import static org.apache.ranger.plugin.client.HadoopConfigHolder.RANGER_LOOKUP_PRINCIPAL;
+
+public class SecurityUtils {
+
+    private static final Log LOG = LogFactory.getLog(SecurityUtils.class);
+    private static final long KERBEROS_SYNCHRONIZATION_TIMEOUT_MS = 180000;
+    private static final String REGISTY_CLIENT_JAAS_SECTION = "RegistryClient";
+
+    public static boolean isHttpsConnection(Map<String, ?> conf) {
+        String urls = conf.get(SCHEMA_REGISTRY_URL.name()).toString();
+        return urls.trim().startsWith("https://");
+    }
+
+    public static SSLContext createSSLContext(Map<String, ?> sslConfigurations, String sslAlgorithm) throws Exception {
+        SSLContext context = SSLContext.getInstance(sslAlgorithm);
+        KeyManager[] km = null;
+        String keyStorePath = (String)sslConfigurations.get("keyStorePath");
+        if (keyStorePath == null || keyStorePath.isEmpty()) {
+            keyStorePath = System.getProperty("javax.net.ssl.keyStore");
+        }
+        String keyStorePassword = (String)sslConfigurations.get("keyStorePassword");
+        if (keyStorePassword == null || keyStorePath.isEmpty()) {
+            keyStorePassword = Optional.ofNullable(System.getProperty("javax.net.ssl.keyStorePassword")).orElse("");
+        }
+        String keyStoreType = (String)sslConfigurations.get("keyStoreType");
+        if (keyStoreType == null || keyStoreType.isEmpty()) {
+            keyStoreType = System.getProperty("javax.net.ssl.keyStoreType");
+        }
+
+        String trustStorePath = (String)sslConfigurations.get("trustStorePath");
+        if (trustStorePath == null || trustStorePath.isEmpty()) {
+            trustStorePath = System.getProperty("javax.net.ssl.trustStore");
+        }
+        String trustStorePassword = (String)sslConfigurations.get("trustStorePassword");
+        if (trustStorePassword == null || trustStorePassword.isEmpty()) {
+            trustStorePassword = Optional.ofNullable(System.getProperty("javax.net.ssl.trustStorePassword")).orElse("");
+        }
+        String trustStoreType = (String)sslConfigurations.get("trustStoreType");
+        if (trustStoreType == null || trustStoreType.isEmpty()) {
+            trustStoreType = System.getProperty("javax.net.ssl.trustStoreType");
+        }
+
+        Object obj = sslConfigurations.get("serverCertValidation");
+        boolean serverCertValidation = (obj == null) || Boolean.parseBoolean(obj.toString());
+
+        if (keyStorePath != null) {
+            KeyStore ks = KeyStore.getInstance(keyStoreType != null ?
+                    keyStoreType : KeyStore.getDefaultType());
+
+            InputStream in = getFileInputStream(keyStorePath);
+
+            try {
+                ks.load(in, keyStorePassword.toCharArray());
+            } finally {
+                if (in != null) {
+                    in.close();
+                }
+            }
+
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+            kmf.init(ks, keyStorePassword.toCharArray());
+            km = kmf.getKeyManagers();
+        }
+        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+        TrustManager[] tm = null;
+        if (serverCertValidation) {
+            if (trustStorePath != null) {
+                KeyStore trustStore = KeyStore.getInstance(trustStoreType != null ?
+                        trustStoreType : KeyStore.getDefaultType());
+                InputStream in = getFileInputStream(trustStorePath);
+                try {
+                    trustStore.load(in, trustStorePassword.toCharArray());
+
+                    trustManagerFactory.init(trustStore);
+
+                    tm = trustManagerFactory.getTrustManagers();
+
+                } finally {
+                    if (in != null) {
+                        in.close();
+                    }
+                }
+            }
+        } else {
+            TrustManager ignoreValidationTM = new X509TrustManager() {
+                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                    // Ignore Server Certificate Validation
+                }
+
+                public X509Certificate[] getAcceptedIssuers() {
+                    return new X509Certificate[0];
+                }
+
+                public void checkServerTrusted(X509Certificate[] chain,
+                                               String authType)
+                        throws CertificateException {
+                    // Ignore Server Certificate Validation
+                }
+            };
+
+            tm  = new TrustManager[] {ignoreValidationTM};
+        }
+        SecureRandom random = new SecureRandom();
+        context.init(km, tm, random);
+
+        return context;
+    }
+
+    static private InputStream getFileInputStream(String path) throws FileNotFoundException {
+        InputStream ret;
+        File f = new File(path);
+        if (f.exists()) {
+            ret = new FileInputStream(f);
+        } else {
+            ret = SecurityUtils.class.getResourceAsStream(path);
+
+            if (ret == null) {
+                if (! path.startsWith("/")) {
+                    ret = SecurityUtils.class.getResourceAsStream("/" + path);
+                }
+            }
+
+            if (ret == null) {
+                ret = ClassLoader.getSystemClassLoader().getResourceAsStream(path);
+                if (ret == null) {
+                    if (! path.startsWith("/")) {
+                        ret = ClassLoader.getSystemResourceAsStream("/" + path);
+                    }
+                }
+            }
+        }
+        return ret;
+    }
+
+    static String getJaasConfigForClientPrincipal(Map<String, ?> conf) {
+        String keytabFile = (String)conf.get(RANGER_LOOKUP_KEYTAB);
+        String principal = (String)conf.get(RANGER_LOOKUP_PRINCIPAL);
+
+        if(keytabFile == null || keytabFile.isEmpty()
+                || principal == null || principal.isEmpty()) {
+            return null;
+        }
+
+        return "com.sun.security.auth.module.Krb5LoginModule required useTicketCache=false principal=\""
+                + principal
+                + "\" useKeyTab=true keyTab=\""
+                + keytabFile
+                + "\";";
+    }
+
+    public static Login initializeSecurityContext(Map<String, ?> conf) {
+        String saslJaasConfig = getJaasConfigForClientPrincipal(conf);
+        boolean kerberosOn = isKerberosEnabled(conf);
+        if (kerberosOn && saslJaasConfig != null) {
+            KerberosLogin kerberosLogin = new KerberosLogin(KERBEROS_SYNCHRONIZATION_TIMEOUT_MS);
+            try {
+                kerberosLogin.configure(new HashMap<>(), REGISTY_CLIENT_JAAS_SECTION, new JaasConfiguration(REGISTY_CLIENT_JAAS_SECTION, saslJaasConfig));
+                kerberosLogin.login();
+                return kerberosLogin;
+            } catch (LoginException e) {
+                LOG.error("Failed to initialize the dynamic JAAS config: " + saslJaasConfig + ". Attempting static JAAS config.");
+            } catch (Exception e) {
+                LOG.error("Failed to parse the dynamic JAAS config. Attempting static JAAS config.", e);
+            }
+        }
+
+        return new NOOPLogin();
+    }
+
+    static boolean isKerberosEnabled(Map<String, ?> conf) {
+        String rangerAuthType = (String) conf.get(RANGER_AUTH_TYPE);
+        String pluginAuthType = (String) conf.get("schema-registry.authentication");
+
+        return rangerAuthType != null
+                && pluginAuthType != null
+                && rangerAuthType.equals(HADOOP_SECURITY_AUTHENTICATION_METHOD)
+                && pluginAuthType.equalsIgnoreCase(HADOOP_SECURITY_AUTHENTICATION_METHOD);
+    }
+}
diff --git a/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/AutocompletionAgentTest.java b/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/AutocompletionAgentTest.java
new file mode 100644
index 0000000..beafae3
--- /dev/null
+++ b/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/AutocompletionAgentTest.java
@@ -0,0 +1,194 @@
+/*
+ * 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.services.schema.registry.client;
+
+import org.apache.ranger.services.schema.registry.client.connection.ISchemaRegistryClient;
+import org.apache.ranger.services.schema.registry.client.util.DefaultSchemaRegistryClientForTesting;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+
+
+public class AutocompletionAgentTest {
+
+
+    @Test
+    public void connectionTest() {
+        ISchemaRegistryClient client = new DefaultSchemaRegistryClientForTesting();
+
+        AutocompletionAgent autocompletionAgent =
+                new AutocompletionAgent("schema-registry", client);
+
+        HashMap<String, Object> res = autocompletionAgent.connectionTest();
+        assertEquals(res.get("connectivityStatus"), true);
+        assertEquals(res.get("message"), "ConnectionTest Successful");
+        assertEquals(res.get("description"), "ConnectionTest Successful");
+        assertNull(res.get("objectId"));
+        assertNull(res.get("fieldName"));
+
+
+        client = new DefaultSchemaRegistryClientForTesting() {
+            public void checkConnection() throws Exception {
+                throw new Exception("Cannot connect to the SR server");
+            }
+        };
+        autocompletionAgent =
+                new AutocompletionAgent("schema-registry", client);
+
+        res = autocompletionAgent.connectionTest();
+        String errMessage = "You can still save the repository and start creating "
+                + "policies, but you would not be able to use autocomplete for "
+                + "resource names. Check server logs for more info.";
+        assertEquals(res.get("connectivityStatus"), false);
+        assertThat(res.get("message"), is(errMessage));
+        assertThat(res.get("description"), is(errMessage));
+        assertNull(res.get("objectId"));
+        assertNull(res.get("fieldName"));
+
+    }
+
+    @Test
+    public void getSchemaGroupList() {
+        ISchemaRegistryClient client = new DefaultSchemaRegistryClientForTesting(){
+            public List<String> getSchemaGroups() {
+                List<String> groups = new ArrayList<>();
+                groups.add("testGroup");
+                return groups;
+            }
+        };
+
+        AutocompletionAgent autocompletionAgent =
+                new AutocompletionAgent("schema-registry", client);
+
+        // Empty initialGroups and the list of groups returned by ISchemaRegistryClient
+        // doesn't contain any groups that starts with 'tesSome'
+        List<String> initialGroups = new ArrayList<>();
+        List<String> res = autocompletionAgent.getSchemaGroupList("tesSome", initialGroups);
+        assertEquals(0, res.size());
+
+        // Empty initialGroups and the list of groups returned by ISchemaRegistryClient
+        // contains a group that starts with 'tes'
+        initialGroups = new ArrayList<>();
+        res = autocompletionAgent.getSchemaGroupList("tes", initialGroups);
+        List<String>  expected = new ArrayList<>();
+        expected.add("testGroup");
+        assertEquals(1, res.size());
+        assertThat(res, is(expected));
+
+        // initialGroups contains one element, list of the groups returned by ISchemaRegistryClient
+        // contains the same values that are already present in initialGroups
+        initialGroups = new ArrayList<>();
+        initialGroups.add("testGroup");
+        res = autocompletionAgent.getSchemaGroupList("tes", initialGroups);
+        expected = new ArrayList<>();
+        expected.add("testGroup");
+        assertEquals(1, res.size());
+        assertThat(res, is(expected));
+
+        // initialGroups contains one element, list of the groups returned by ISchemaRegistryClient
+        // contains one element too, that is not equal to the element in initialGroups
+        initialGroups = new ArrayList<>();
+        initialGroups.add("testGroup2");
+        res = autocompletionAgent.getSchemaGroupList("tes", initialGroups);
+        expected = new ArrayList<>();
+        expected.add("testGroup2");
+        expected.add("testGroup");
+        assertEquals(2, res.size());
+        assertThat(res, is(expected));
+
+    }
+
+    @Test
+    public void getSchemaMetadataList() {
+        ISchemaRegistryClient client = new DefaultSchemaRegistryClientForTesting(){
+
+            public List<String> getSchemaNames(List<String> schemaGroup) {
+                if(!schemaGroup.contains("Group1")) {
+                    return new ArrayList<>();
+                }
+                List<String> schemas = new ArrayList<>();
+                schemas.add("testSchema");
+                return schemas;
+            }
+        };
+
+        AutocompletionAgent autocompletionAgent =
+                new AutocompletionAgent("schema-registry", client);
+
+        List<String> groupList = new ArrayList<>();
+        groupList.add("Group1");
+        groupList.add("Group2");
+        List<String> res = autocompletionAgent.getSchemaMetadataList("tes", groupList, new ArrayList<>());
+        List<String> expected = new ArrayList<>();
+        expected.add("testSchema");
+        assertEquals(1, res.size());
+        assertThat(res, is(expected));
+
+        res = autocompletionAgent.getSchemaMetadataList("tesSome", groupList, new ArrayList<>());
+        assertEquals(0, res.size());
+    }
+
+    @Test
+    public void getBranchList() {
+        ISchemaRegistryClient client = new DefaultSchemaRegistryClientForTesting(){
+
+            public List<String> getSchemaBranches(String schemaMetadataName) {
+                if(!schemaMetadataName.equals("Schema1")) {
+                    return new ArrayList<>();
+                }
+                List<String> branches = new ArrayList<>();
+                branches.add("testBranch");
+                return branches;
+            }
+
+
+            public List<String> getSchemaNames(List<String> schemaGroup) {
+                if(!schemaGroup.contains("Group1")) {
+                    return new ArrayList<>();
+                }
+                List<String> schemas = new ArrayList<>();
+                schemas.add("Schema1");
+                return schemas;
+            }
+        };
+
+        AutocompletionAgent autocompletionAgent =
+                new AutocompletionAgent("schema-registry", client);
+
+        List<String> schemaList = new ArrayList<>();
+        schemaList.add("Schema1");
+        schemaList.add("Schema2");
+        List<String> groups = new ArrayList<>();
+        groups.add("Group1");
+        List<String> res = autocompletionAgent.getBranchList("tes", groups, schemaList, new ArrayList<>());
+        List<String> expected = new ArrayList<>();
+        expected.add("testBranch");
+        assertEquals(1, res.size());
+        assertThat(res, is(expected));
+
+        res = autocompletionAgent.getSchemaMetadataList("tesSome", schemaList, new ArrayList<>());
+        assertEquals(0, res.size());
+    }
+}
\ No newline at end of file
diff --git a/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/SchemaRegistryResourceMgrTest.java b/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/SchemaRegistryResourceMgrTest.java
new file mode 100644
index 0000000..33860b3
--- /dev/null
+++ b/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/SchemaRegistryResourceMgrTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.services.schema.registry.client;
+
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+import org.apache.ranger.services.schema.registry.client.util.TestAutocompletionAgent;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+public class SchemaRegistryResourceMgrTest {
+
+    @Test
+    public void getSchemaRegistryResources() throws Exception {
+        String serviceName = "schema-registry";
+        Map<String, String> configs = new HashMap<>();
+        configs.put("schema.registry.url", "http://dummyname:8081");
+        AutocompletionAgent client = new TestAutocompletionAgent("schema-registry", configs);
+
+
+        ResourceLookupContext lookupContext = new ResourceLookupContext();
+        lookupContext.setResources(new HashMap<>());
+        List<String> groups = new ArrayList<>(), schemas = new ArrayList<>(), branches = new ArrayList<>();
+        groups.add("Group1");
+        schemas.add("Schema1");
+        branches.add("Branch1");
+
+        lookupContext.getResources().put("schema-group", groups);
+        lookupContext.getResources().put("schema-metadata", schemas);
+        lookupContext.getResources().put("schema-branch", branches);
+
+        lookupContext.setResourceName("schema-group");
+        lookupContext.setUserInput("test");
+        List<String> res = SchemaRegistryResourceMgr.getSchemaRegistryResources(serviceName,
+                configs,
+                lookupContext,
+                client);
+        List<String> expected = new ArrayList<>();
+        expected.add("Group1"); expected.add("testGroup");
+        assertThat(res, is(expected));
+
+        lookupContext.setResourceName("schema-metadata");
+        lookupContext.setUserInput("testS");
+        res = SchemaRegistryResourceMgr.getSchemaRegistryResources(serviceName,
+                configs,
+                lookupContext,
+                client);
+        expected = new ArrayList<>();
+        expected.add("Schema1"); expected.add("testSchema");
+        assertThat(res, is(expected));
+
+        lookupContext.setResourceName("schema-branch");
+        lookupContext.setUserInput("testB");
+        res = SchemaRegistryResourceMgr.getSchemaRegistryResources(serviceName,
+                configs,
+                lookupContext,
+                client);
+        expected = new ArrayList<>();
+        expected.add("Branch1"); expected.add("testBranch");
+        assertThat(res, is(expected));
+
+        lookupContext.setResourceName("schema-version");
+        lookupContext.setUserInput("*");
+        res = SchemaRegistryResourceMgr.getSchemaRegistryResources(serviceName,
+                configs,
+                lookupContext,
+                client);
+        expected = new ArrayList<>();
+        expected.add("*");
+        assertThat(res, is(expected));
+
+        lookupContext.setResourceName("serde");
+        res = SchemaRegistryResourceMgr.getSchemaRegistryResources(serviceName,
+                configs,
+                lookupContext,
+                client);
+        assertThat(res, is(expected));
+
+        lookupContext.setResourceName("registry-service");
+        res = SchemaRegistryResourceMgr.getSchemaRegistryResources(serviceName,
+                configs,
+                lookupContext,
+                client);
+        assertThat(res, is(expected));
+
+    }
+}
\ No newline at end of file
diff --git a/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/connection/DefaultSchemaRegistryClientTest.java b/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/connection/DefaultSchemaRegistryClientTest.java
new file mode 100644
index 0000000..7eaaab9
--- /dev/null
+++ b/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/connection/DefaultSchemaRegistryClientTest.java
@@ -0,0 +1,190 @@
+/*
+ * 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.services.schema.registry.client.connection;
+
+import com.google.common.io.Resources;
+import com.hortonworks.registries.schemaregistry.SchemaMetadata;
+import com.hortonworks.registries.schemaregistry.SchemaVersion;
+import com.hortonworks.registries.schemaregistry.webservice.LocalSchemaRegistryServer;
+import org.apache.commons.io.IOUtils;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static com.hortonworks.registries.schemaregistry.client.SchemaRegistryClient.Configuration.SCHEMA_REGISTRY_URL;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+
+public class DefaultSchemaRegistryClientTest {
+
+    private static final String V1_API_PATH = "api/v1";
+
+    private static LocalSchemaRegistryServer localSchemaRegistryServer;
+
+    private static ISchemaRegistryClient client;
+
+    @BeforeClass
+    public static void init() throws Exception {
+        localSchemaRegistryServer =
+                new LocalSchemaRegistryServer(getFilePath("ssl-schema-registry.yaml"));
+
+        try {
+            localSchemaRegistryServer.start();
+        } catch (Exception e){
+            localSchemaRegistryServer.stop();
+            throw e;
+        }
+
+        SchemaMetadata schemaMetadata1 = new SchemaMetadata
+                .Builder("Schema1")
+                .type("avro")
+                .schemaGroup("Group1")
+                .description("description")
+                .build();
+
+        SchemaMetadata schemaMetadata2 = new SchemaMetadata
+                .Builder("Schema2")
+                .type("avro")
+                .schemaGroup("Group2")
+                .description("description")
+                .build();
+
+        SchemaMetadata schemaMetadata3 = new SchemaMetadata
+                .Builder("Schema3")
+                .type("avro")
+                .schemaGroup("Group3")
+                .description("description")
+                .build();
+
+        com.hortonworks.registries.schemaregistry.client.SchemaRegistryClient client = getClient("ssl-schema-registry-client.yaml");
+
+        client.registerSchemaMetadata(schemaMetadata1);
+        client.registerSchemaMetadata(schemaMetadata2);
+        client.registerSchemaMetadata(schemaMetadata3);
+
+        SchemaVersion sv = new SchemaVersion(getSchema("schema-text3.avcs"),
+                "Initial version of the schema");
+        client.addSchemaVersion(schemaMetadata3, sv);
+
+        ///////////////////////////////////////////////
+        Map<String, Object> conf = new HashMap<>();
+        conf.put(SCHEMA_REGISTRY_URL.name(), "https://localhost:" + localSchemaRegistryServer.getLocalPort());
+        String keyStorePath = "./src/test/resources/keystore.jks";
+        String keyStorePassword = "password";
+        String keyStoreType = "jks";
+
+        String trustStorePath = "./src/test/resources/truststore.jks";
+        String trustStorePassword = "password";
+        String trustStoreType = "jks";
+        conf.put("keyStorePath", keyStorePath);
+        conf.put("keyStorePassword", keyStorePassword);
+        conf.put("keyStoreType", keyStoreType);
+
+        conf.put("trustStorePath", trustStorePath);
+        conf.put("trustStorePassword", trustStorePassword);
+        conf.put("trustStoreType", trustStoreType);
+
+        DefaultSchemaRegistryClientTest.client = new DefaultSchemaRegistryClient(conf);
+
+    }
+
+    private static String getSchema(String schemaFileName) throws Exception {
+        try (FileInputStream fis = new FileInputStream(getFilePath(schemaFileName))) {
+            org.apache.avro.Schema.Parser parser = new org.apache.avro.Schema.Parser();
+            return parser.parse(fis).toString();
+        } catch (Exception e) {
+            throw new Exception("Failed to read schema text from : "
+                    + getFilePath(schemaFileName), e);
+        }
+
+    }
+
+    private static String getFilePath(String serverYAMLFileName) throws URISyntaxException {
+        return new File(Resources.getResource(serverYAMLFileName)
+                .toURI())
+                .getAbsolutePath();
+    }
+
+    private static com.hortonworks.registries.schemaregistry.client.SchemaRegistryClient getClient(String clientYAMLFileName) throws Exception {
+        String registryURL = localSchemaRegistryServer.getLocalURL() + V1_API_PATH;
+        Map<String, Object> conf = new HashMap<>();
+        try (FileInputStream fis = new FileInputStream(getFilePath(clientYAMLFileName))) {
+            conf = (Map<String, Object>) new Yaml().load(IOUtils.toString(fis, "UTF-8"));
+            conf.put("schema.registry.url", registryURL);
+        } catch(Exception e) {
+            throw new Exception("Failed to export schema client configuration for yaml : " + getFilePath(clientYAMLFileName), e);
+        }
+        conf.put(SCHEMA_REGISTRY_URL.name(), registryURL);
+
+        return new com.hortonworks.registries.schemaregistry.client.SchemaRegistryClient(conf);
+    }
+
+    @Test
+    public void getSchemaGroups() {
+        List<String> groups = client.getSchemaGroups();
+        assertThat(groups.size(), is(3));
+        assertTrue(groups.contains("Group1"));
+        assertTrue(groups.contains("Group2"));
+        assertTrue(groups.contains("Group3"));
+    }
+
+    @Test
+    public void getSchemaNames() {
+        List<String> groups = new ArrayList<>();
+        groups.add("Group1");
+        groups.add("Group2");
+        List<String> schemas = client.getSchemaNames(groups);
+        assertThat(schemas.size(), is(2));
+        assertTrue(schemas.contains("Schema1"));
+        assertTrue(schemas.contains("Schema2"));
+    }
+
+    @Test
+    public void getSchemaBranches() {
+        List<String> branches = client.getSchemaBranches("Schema1");
+        assertTrue(branches.isEmpty());
+        branches = client.getSchemaBranches("Schema3");
+        assertThat(branches.size(), is(1));
+        assertThat(branches.get(0), is("MASTER"));
+    }
+
+    @Test
+    public void checkConnection() {
+        try {
+            client.checkConnection();
+        } catch (Exception e) {
+            fail("No Exception should be thrown");
+        }
+    }
+
+    @Test(expected = Exception.class)
+    public void checkConnection2() throws Exception {
+        new DefaultSchemaRegistryClient(new HashMap<>()).checkConnection();
+    }
+}
\ No newline at end of file
diff --git a/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/connection/util/SecurityUtilsTest.java b/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/connection/util/SecurityUtilsTest.java
new file mode 100644
index 0000000..541056c
--- /dev/null
+++ b/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/connection/util/SecurityUtilsTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.services.schema.registry.client.connection.util;
+
+import org.junit.Test;
+
+import javax.net.ssl.SSLContext;
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.hortonworks.registries.schemaregistry.client.SchemaRegistryClient.Configuration.SCHEMA_REGISTRY_URL;
+import static org.apache.ranger.plugin.client.HadoopConfigHolder.RANGER_AUTH_TYPE;
+import static org.apache.ranger.plugin.client.HadoopConfigHolder.RANGER_LOOKUP_KEYTAB;
+import static org.apache.ranger.plugin.client.HadoopConfigHolder.RANGER_LOOKUP_PRINCIPAL;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class SecurityUtilsTest {
+
+    @Test
+    public void isHttpsConnection() {
+        Map<String, String> conf = new HashMap();
+        conf.put(SCHEMA_REGISTRY_URL.name(), "https://dummy:8081");
+        assertTrue(SecurityUtils.isHttpsConnection(conf));
+
+        conf = new HashMap();
+        conf.put(SCHEMA_REGISTRY_URL.name(), "http://dummy:8081");
+        assertFalse(SecurityUtils.isHttpsConnection(conf));
+    }
+
+    @Test
+    public void createSSLContext() throws Exception {
+        String keyStorePath = "keystore.jks";
+        String keyStorePassword = "password";
+        String keyStoreType = "jks";
+
+        String trustStorePath = "trustsrore.jks";
+        String trustStorePassword = "password";
+        String trustStoreType = "jks";
+
+        Map<String, String> conf = new HashMap();
+        SSLContext sslContext = SecurityUtils.createSSLContext(conf, "TLS");
+        assertTrue(sslContext != null);
+
+        conf.put("keyStorePath", keyStorePath);
+        conf.put("keyStorePassword", keyStorePassword);
+        conf.put("keyStoreType", keyStoreType);
+
+        conf.put("trustStorePath", trustStorePath);
+        conf.put("trustStorePassword", trustStorePassword);
+        conf.put("trustStoreType", trustStoreType);
+        sslContext = SecurityUtils.createSSLContext(conf, "TLS");
+
+        assertTrue(sslContext != null);
+
+    }
+
+    @Test
+    public void getJaasConfigForClientPrincipal() {
+        Map<String, String> conf = new HashMap();
+        assertNull(SecurityUtils.getJaasConfigForClientPrincipal(conf));
+        conf.put(RANGER_LOOKUP_KEYTAB, "/tmp/rangerlookup.keytab");
+        assertNull(SecurityUtils.getJaasConfigForClientPrincipal(conf));
+        conf.put(RANGER_LOOKUP_PRINCIPAL, "rangerlookup");
+
+        String expected = "com.sun.security.auth.module.Krb5LoginModule" +
+                " required useTicketCache=false principal=\"rangerlookup\" " +
+                "useKeyTab=true keyTab=\"/tmp/rangerlookup.keytab\";";
+        String actual = SecurityUtils.getJaasConfigForClientPrincipal(conf);
+        assertEquals(actual, expected);
+    }
+
+
+    @Test
+    public void isKerberosEnabled() {
+        Map<String, String> conf = new HashMap();
+
+        conf.put(RANGER_AUTH_TYPE, "kerberos");
+        conf.put("schema-registry.authentication", "kerberos");
+        assertTrue(SecurityUtils.isKerberosEnabled(conf));
+
+        conf = new HashMap();
+        assertFalse(SecurityUtils.isKerberosEnabled(conf));
+
+        conf = new HashMap();
+        conf.put(RANGER_AUTH_TYPE, "kerberos");
+        assertFalse(SecurityUtils.isKerberosEnabled(conf));
+
+        conf = new HashMap();
+        conf.put("schema-registry.authentication", "kerberos");
+        assertFalse(SecurityUtils.isKerberosEnabled(conf));
+
+        conf = new HashMap();
+        conf.put(RANGER_AUTH_TYPE, "kerberos");
+        conf.put("schema-registry.authentication", "Something wrong");
+        assertFalse(SecurityUtils.isKerberosEnabled(conf));
+
+        conf = new HashMap();
+        conf.put("schema-registry.authentication", "kerberos");
+        conf.put(RANGER_AUTH_TYPE, "Something wrong");
+        assertFalse(SecurityUtils.isKerberosEnabled(conf));
+
+    }
+}
\ No newline at end of file
diff --git a/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/util/AcceptAllHostnameVerifier.java b/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/util/AcceptAllHostnameVerifier.java
new file mode 100644
index 0000000..7d01860
--- /dev/null
+++ b/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/util/AcceptAllHostnameVerifier.java
@@ -0,0 +1,28 @@
+/*
+ * 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.services.schema.registry.client.util;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+
+public class AcceptAllHostnameVerifier implements HostnameVerifier {
+    @Override
+    public boolean verify(String s, SSLSession sslSession) {
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/util/DefaultSchemaRegistryClientForTesting.java b/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/util/DefaultSchemaRegistryClientForTesting.java
new file mode 100644
index 0000000..083dd6b
--- /dev/null
+++ b/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/util/DefaultSchemaRegistryClientForTesting.java
@@ -0,0 +1,46 @@
+/*
+ * 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.services.schema.registry.client.util;
+
+import org.apache.ranger.services.schema.registry.client.connection.ISchemaRegistryClient;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DefaultSchemaRegistryClientForTesting implements ISchemaRegistryClient {
+
+    @Override
+    public List<String> getSchemaGroups() {
+        return new ArrayList<>();
+    }
+
+    @Override
+    public List<String> getSchemaNames(List<String> schemaGroup) {
+        return new ArrayList<>();
+    }
+
+    @Override
+    public List<String> getSchemaBranches(String schemaMetadataName) {
+        return new ArrayList<>();
+    }
+
+    @Override
+    public void checkConnection() throws Exception {
+
+    }
+}
diff --git a/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/util/TestAutocompletionAgent.java b/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/util/TestAutocompletionAgent.java
new file mode 100644
index 0000000..3dd8748
--- /dev/null
+++ b/plugin-schema-registry/src/test/java/org/apache/ranger/services/schema/registry/client/util/TestAutocompletionAgent.java
@@ -0,0 +1,59 @@
+/*
+ * 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.services.schema.registry.client.util;
+
+import org.apache.ranger.services.schema.registry.client.AutocompletionAgent;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class TestAutocompletionAgent extends AutocompletionAgent {
+    public TestAutocompletionAgent(String serviceName, Map<String, String> configs) {
+        super(serviceName, configs);
+    }
+
+    @Override
+    public List<String> getSchemaGroupList(String lookupGroupName, List<String> groupList) {
+        List<String> res = new ArrayList<>(groupList);
+        res.add("testGroup");
+
+        return res;
+    }
+
+    @Override
+    public List<String> getSchemaMetadataList(String finalSchemaMetadataName,
+                                              List<String> schemaGroupList,
+                                              List<String> schemaMetadataList) {
+        List<String> res = new ArrayList<>(schemaMetadataList);
+        res.add("testSchema");
+
+        return res;
+    }
+
+    @Override
+    public List<String> getBranchList(String lookupBranchName,
+                                      List<String> groups,
+                                      List<String> schemaList,
+                                      List<String> branchList) {
+        List<String> res = new ArrayList<>(branchList);
+        res.add("testBranch");
+
+        return res;
+    }
+}
diff --git a/plugin-schema-registry/src/test/resources/keystore.jks b/plugin-schema-registry/src/test/resources/keystore.jks
new file mode 100644
index 0000000..8e8a4c7
Binary files /dev/null and b/plugin-schema-registry/src/test/resources/keystore.jks differ
diff --git a/plugin-schema-registry/src/test/resources/schema-text3.avcs b/plugin-schema-registry/src/test/resources/schema-text3.avcs
new file mode 100644
index 0000000..21d9c2a
--- /dev/null
+++ b/plugin-schema-registry/src/test/resources/schema-text3.avcs
@@ -0,0 +1,9 @@
+{
+  "type": "record",
+  "namespace": "com.example",
+  "name": "FullName",
+  "fields": [
+    { "name": "first", "type": "string" },
+    { "name": "last", "type": "string" }
+  ]
+}
\ No newline at end of file
diff --git a/plugin-schema-registry/src/test/resources/ssl-schema-registry-client.yaml b/plugin-schema-registry/src/test/resources/ssl-schema-registry-client.yaml
new file mode 100644
index 0000000..ff46570
--- /dev/null
+++ b/plugin-schema-registry/src/test/resources/ssl-schema-registry-client.yaml
@@ -0,0 +1,27 @@
+schema.registry.url : "__registry_url"
+schema.registry.client.local.jars.path : "/tmp/schema-registry/local-jars"
+schema.registry.client.class.loader.cache.size : 1024
+schema.registry.client.class.loader.cache.expiry.interval : 3600
+schema.registry.client.schema.version.cache.size : 1024
+schema.registry.client.schema.version.cache.expiry.interval : 300
+schema.registry.client.schema.metadata.cache.expiry.interval : 300
+schema.registry.client.schema.text.cache.size : 1024
+schema.registry.client.schema.text.cache.expiry.interval : 300
+schema.registry.client.url.selector : "com.hortonworks.registries.schemaregistry.client.FailoverUrlSelector"
+
+schema.registry.client.ssl:
+  protocol: SSL
+  hostnameVerifierClass: org.apache.ranger.services.schema.registry.client.util.AcceptAllHostnameVerifier
+  keyStoreType: JKS
+  keyStorePath: ./src/test/resources/keystore.jks
+  keyStorePassword: password
+#  keyPassword:
+#  keyStoreProvider:
+#  keyManagerFactoryProvider:
+#  keyManagerFactoryAlgorithm:
+  trustStoreType: JKS
+  trustStorePath: ./src/test/resources/truststore.jks
+  trustStorePassword: password
+#  trustStoreProvider:
+#  trustManagerFactoryProvider:
+#  trustManagerFactoryAlgorithm:
\ No newline at end of file
diff --git a/plugin-schema-registry/src/test/resources/ssl-schema-registry.yaml b/plugin-schema-registry/src/test/resources/ssl-schema-registry.yaml
new file mode 100644
index 0000000..dc84998
--- /dev/null
+++ b/plugin-schema-registry/src/test/resources/ssl-schema-registry.yaml
@@ -0,0 +1,79 @@
+# registries configuration
+modules:
+  - name: schema-registry
+    className: com.hortonworks.registries.schemaregistry.webservice.SchemaRegistryModule
+    config:
+      schemaProviders:
+        - providerClass: "com.hortonworks.registries.schemaregistry.avro.AvroSchemaProvider"
+          defaultSerializerClass: "com.hortonworks.registries.schemaregistry.serdes.avro.AvroSnapshotSerializer"
+          defaultDeserializerClass: "com.hortonworks.registries.schemaregistry.serdes.avro.AvroSnapshotDeserializer"
+      # schema cache properties
+      # inmemory schema versions cache size
+      schemaCacheSize: 10000
+      # inmemory schema version cache entry expiry interval after access
+      schemaCacheExpiryInterval: 3600
+
+
+servletFilters:
+ - className: "com.hortonworks.registries.schemaregistry.webservice.RewriteUriFilter"
+   params:
+     # value format is [<targetpath>,<paths-should-be-redirected-to>,*|]*
+     # below /subjects and /schemas/ids are forwarded to /api/v1/confluent
+     forwardPaths: "/api/v1/confluent,/subjects/*,/schemas/ids/*"
+     redirectPaths: "/ui/,/"
+
+
+fileStorageConfiguration:
+  className: "com.hortonworks.registries.common.util.LocalFileSystemStorage"
+  properties:
+    directory: "/tmp/storage"
+
+
+storageProviderConfiguration:
+  providerClass: "com.hortonworks.registries.storage.impl.memory.InMemoryStorageManager"
+
+#enable CORS, may want to disable in production
+enableCors: true
+
+## swagger configuration
+swagger:
+  resourcePackage: com.hortonworks.registries.schemaregistry.webservice
+
+
+server:
+  applicationConnectors:
+    - type: https
+      port: 0
+      keyStorePath: ./src/test/resources/keystore.jks
+      keyStorePassword: password
+      trustStorePath: ./src/test/resources/truststore.jks
+      trustStorePassword: password
+      needClientAuth: true
+      validateCerts: false
+      validatePeers: false
+  adminConnectors:
+    - type: https
+      port: 0
+      keyStorePath: ./src/test/resources/keystore.jks
+      keyStorePassword: password
+      trustStorePath: ./src/test/resources/truststore.jks
+      trustStorePassword: password
+      needClientAuth: true
+      validateCerts: false
+      validatePeers: false
+
+# Logging settings.
+logging:
+
+  # The default level of all loggers. Can be OFF, ERROR, WARN, INFO, DEBUG, TRACE, or ALL.
+  level: INFO
+
+  # Logger-specific levels.
+  loggers:
+
+    # Sets the level for 'com.example.app' to DEBUG.
+    com.hortonworks.registries: DEBUG
+
+
+  appenders:
+    - type: console
diff --git a/plugin-schema-registry/src/test/resources/truststore.jks b/plugin-schema-registry/src/test/resources/truststore.jks
new file mode 100644
index 0000000..3d81722
Binary files /dev/null and b/plugin-schema-registry/src/test/resources/truststore.jks differ
diff --git a/pom.xml b/pom.xml
index dde449d..22926fd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -267,6 +267,7 @@
                 <module>ranger-examples</module>
                 <module>ranger-tools</module>
                 <module>plugin-atlas</module>
+                <module>plugin-schema-registry</module>
                 <module>plugin-sqoop</module>
                 <module>ranger-sqoop-plugin-shim</module>
                 <module>plugin-kylin</module>
@@ -549,6 +550,7 @@
                 <module>ranger-examples</module>
                 <module>ranger-tools</module>
                 <module>plugin-atlas</module>
+                <module>plugin-schema-registry</module>
                 <module>plugin-sqoop</module>
                 <module>ranger-sqoop-plugin-shim</module>
                 <module>plugin-kylin</module>
@@ -631,6 +633,7 @@
                 <module>ranger-examples</module>
                 <module>ranger-tools</module>
                 <module>plugin-atlas</module>
+                <module>plugin-schema-registry</module>
                 <module>plugin-sqoop</module>
                 <module>ranger-sqoop-plugin-shim</module>
                 <module>plugin-kylin</module>
@@ -965,6 +968,8 @@
                         <exclude>**/test/resources/**/*.json</exclude>
                         <exclude>**/test/resources/**/*.txt</exclude>
                         <exclude>**/test/resources/**/*.csv</exclude>
+                        <exclude>**/test/resources/**/*.yaml</exclude>
+                        <exclude>**/test/resources/**/*.avcs</exclude>
                         <exclude>**/main/resources/**/*.json</exclude>
                         <exclude>**/samples/**/*.json</exclude>
                         <exclude>**/.externalToolBuilders/*</exclude>