You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by sm...@apache.org on 2019/09/03 13:43:19 UTC

[airavata-custos] 24/45: migrated sharing registry service into custos

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

smarru pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/airavata-custos.git

commit daf1e71468bd6370f06a3f4d5f5ab06ab8ad04cd
Author: Aarushi <aa...@gmail.com>
AuthorDate: Wed Aug 14 14:34:33 2019 -0400

    migrated sharing registry service into custos
---
 custos-client/pom.xml                              |     6 +
 .../SharingRegistryServiceClientFactory.java       |    44 +
 custos-commons/custos-server.properties            |     0
 .../org/apache/custos/commons/utils/Constants.java |     4 +
 .../custos/commons/utils/ServerSettings.java       |     7 +-
 custos-sharing-registry-service/pom.xml            |    21 +
 .../sharing-registry-distribution/pom.xml          |    87 +
 .../src/main/assembly/bin-assembly.xml             |    75 +
 .../src/main/resources/bin/setenv.sh               |    61 +
 .../src/main/resources/bin/sharing-registry.sh     |    90 +
 .../sharing-registry-server/pom.xml                |   130 +
 .../sharing/registry/db/entities/DomainEntity.java |   116 +
 .../sharing/registry/db/entities/EntityEntity.java |   219 +
 .../sharing/registry/db/entities/EntityPK.java     |    76 +
 .../registry/db/entities/EntityTypeEntity.java     |   130 +
 .../sharing/registry/db/entities/EntityTypePK.java |    76 +
 .../registry/db/entities/GroupAdminEntity.java     |    80 +
 .../sharing/registry/db/entities/GroupAdminPK.java |    66 +
 .../db/entities/GroupMembershipEntity.java         |   126 +
 .../registry/db/entities/GroupMembershipPK.java    |    88 +
 .../registry/db/entities/PermissionTypeEntity.java |   128 +
 .../registry/db/entities/PermissionTypePK.java     |    76 +
 .../registry/db/entities/SharingEntity.java        |   149 +
 .../sharing/registry/db/entities/SharingPK.java    |   116 +
 .../sharing/registry/db/entities/UserEntity.java   |   161 +
 .../registry/db/entities/UserGroupEntity.java      |   178 +
 .../sharing/registry/db/entities/UserGroupPK.java  |    75 +
 .../sharing/registry/db/entities/UserPK.java       |    75 +
 .../db/repositories/AbstractRepository.java        |   168 +
 .../registry/db/repositories/DomainRepository.java |    33 +
 .../registry/db/repositories/EntityRepository.java |   173 +
 .../db/repositories/EntityTypeRepository.java      |    34 +
 .../db/repositories/GroupAdminRepository.java      |    17 +
 .../db/repositories/GroupMembershipRepository.java |   104 +
 .../db/repositories/PermissionTypeRepository.java  |    52 +
 .../db/repositories/SharingRepository.java         |   115 +
 .../db/repositories/UserGroupRepository.java       |    95 +
 .../registry/db/repositories/UserRepository.java   |    79 +
 .../sharing/registry/db/utils/Committer.java       |    26 +
 .../sharing/registry/db/utils/DBConstants.java     |   106 +
 .../custos/sharing/registry/db/utils/JPAUtils.java |    35 +
 .../registry/db/utils/ObjectMapperSingleton.java   |    38 +
 .../db/utils/SharingRegistryDBInitConfig.java      |    47 +
 .../db/utils/SharingRegistryJDBCConfig.java        |    67 +
 .../custos/sharing/registry/server/ServerMain.java |   101 +
 .../registry/server/SharingRegistryServer.java     |   191 +
 .../server/SharingRegistryServerHandler.java       |  1273 +
 .../src/main/resources/META-INF/persistence.xml    |    16 +
 .../src/main/resources/airavata.jks                |   Bin 0 -> 1410 bytes
 .../src/main/resources/client_truststore.jks       |   Bin 0 -> 5312 bytes
 .../src/main/resources/sharing-registry-derby.sql  |   147 +
 .../src/main/resources/sharing-registry-mysql.sql  |   146 +
 .../apache/custos/sharing/registry/CipresTest.java |   632 +
 .../registry/SharingRegistryServerHandlerTest.java |   386 +
 .../registry/SharingRegistryServiceTest.java       |   419 +
 .../src/test/resources/airavata.jks                |   Bin 0 -> 1410 bytes
 .../src/test/resources/client_truststore.jks       |   Bin 0 -> 5312 bytes
 .../src/test/resources/logback.xml                 |    31 +
 .../sharing-registry-stubs/pom.xml                 |    77 +
 .../SharingRegistryServiceClientFactory.java       |    44 +
 .../custos/sharing/registry/models/Domain.java     |   805 +
 .../registry/models/DuplicateEntryException.java   |   377 +
 .../custos/sharing/registry/models/Entity.java     |  1663 +
 .../sharing/registry/models/EntitySearchField.java |    79 +
 .../custos/sharing/registry/models/EntityType.java |   908 +
 .../custos/sharing/registry/models/GroupAdmin.java |   589 +
 .../sharing/registry/models/GroupCardinality.java  |    48 +
 .../sharing/registry/models/GroupChildType.java    |    47 +
 .../sharing/registry/models/GroupMembership.java   |   918 +
 .../custos/sharing/registry/models/GroupType.java  |    47 +
 .../sharing/registry/models/PermissionType.java    |   908 +
 .../sharing/registry/models/SearchCondition.java   |    64 +
 .../sharing/registry/models/SearchCriteria.java    |   628 +
 .../custos/sharing/registry/models/Sharing.java    |  1132 +
 .../registry/models/SharingRegistryException.java  |   374 +
 .../sharing/registry/models/SharingType.java       |    50 +
 .../custos/sharing/registry/models/User.java       |  1246 +
 .../custos/sharing/registry/models/UserGroup.java  |  1427 +
 .../registry/models/sharing_modelsConstants.java   |    14 +
 .../service/cpi/SharingRegistryService.java        | 67599 +++++++++++++++++++
 .../registry/service/cpi/sharing_cpiConstants.java |    14 +
 .../sharing-service-docs/api-docs/index.html       |   104 +
 .../sharing-service-docs/api-docs/sharing_cpi.html |   389 +
 .../api-docs/sharing_models.html                   |   308 +
 .../sharing-service-docs/api-docs/style.css        |   184 +
 .../sharing-service-docs/index.html                |   389 +
 .../sharing-service-docs/sharing_overview.png      |   Bin 0 -> 49205 bytes
 .../sharing-service-docs/style.css                 |   194 +
 .../thrift_models/thrift-gen.sh                    |    43 +
 .../src/main/resources/custos-server.properties    |    17 +
 .../database_scripts/init/01-databases.sql         |   326 +-
 pom.xml                                            |     4 +
 .../sharing-service/sharing-cpi/sharing_cpi.thrift |   274 +
 .../sharing-models/sharing_models.thrift           |   303 +
 94 files changed, 88582 insertions(+), 2 deletions(-)

diff --git a/custos-client/pom.xml b/custos-client/pom.xml
index 7c241a8..58f34c4 100644
--- a/custos-client/pom.xml
+++ b/custos-client/pom.xml
@@ -30,6 +30,12 @@
             <artifactId>tenant-profile-service</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-sharing-registry-stubs</artifactId>
+            <version>1.0-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
     <properties>
         <maven.compiler.source>1.8</maven.compiler.source>
diff --git a/custos-client/src/main/java/org/apache/custos/client/sharing/service/SharingRegistryServiceClientFactory.java b/custos-client/src/main/java/org/apache/custos/client/sharing/service/SharingRegistryServiceClientFactory.java
new file mode 100644
index 0000000..3fc60a4
--- /dev/null
+++ b/custos-client/src/main/java/org/apache/custos/client/sharing/service/SharingRegistryServiceClientFactory.java
@@ -0,0 +1,44 @@
+/**
+ *
+ * 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.custos.client.sharing.service;
+
+import org.apache.custos.sharing.registry.models.SharingRegistryException;
+import org.apache.custos.sharing.registry.service.cpi.SharingRegistryService;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.transport.TTransportException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SharingRegistryServiceClientFactory {
+    private final static Logger logger = LoggerFactory.getLogger(SharingRegistryServiceClientFactory.class);
+
+    public static SharingRegistryService.Client createSharingRegistryClient(String serverHost, int serverPort) throws SharingRegistryException {
+        try {
+            TSocket e = new TSocket(serverHost, serverPort);
+            e.open();
+            TBinaryProtocol protocol = new TBinaryProtocol(e);
+            return new SharingRegistryService.Client(protocol);
+        } catch (TTransportException var4) {
+            logger.error("failed to create sharing registry client", var4);
+            throw new SharingRegistryException();
+        }
+    }
+}
\ No newline at end of file
diff --git a/custos-commons/custos-server.properties b/custos-commons/custos-server.properties
deleted file mode 100644
index e69de29..0000000
diff --git a/custos-commons/src/main/java/org/apache/custos/commons/utils/Constants.java b/custos-commons/src/main/java/org/apache/custos/commons/utils/Constants.java
index 7bb6c8e..ace2e06 100644
--- a/custos-commons/src/main/java/org/apache/custos/commons/utils/Constants.java
+++ b/custos-commons/src/main/java/org/apache/custos/commons/utils/Constants.java
@@ -36,4 +36,8 @@ public final class Constants {
 
     //constants in XACML authorization response.
     public static final String PERMIT = "Permit";
+
+    //security related constants
+    public static final String IS_SHARING_TLS_ENABLED = "sharing.tls.enabled";
+    public static final String TLS_CLIENT_TIMEOUT = "TLS.client.timeout";
 }
diff --git a/custos-commons/src/main/java/org/apache/custos/commons/utils/ServerSettings.java b/custos-commons/src/main/java/org/apache/custos/commons/utils/ServerSettings.java
index 7397d51..46f0453 100644
--- a/custos-commons/src/main/java/org/apache/custos/commons/utils/ServerSettings.java
+++ b/custos-commons/src/main/java/org/apache/custos/commons/utils/ServerSettings.java
@@ -88,5 +88,10 @@ public class ServerSettings extends ApplicationSettings {
     public static String getProfileServiceServerPort() throws ApplicationSettingsException {
         return getSetting(ServerSettings.PROFILE_SERVICE_SERVER_PORT);
     }
-
+    public static boolean isSharingTLSEnabled() throws ApplicationSettingsException {
+        return Boolean.valueOf(getSetting(Constants.IS_SHARING_TLS_ENABLED));
+    }
+    public static int getTLSClientTimeout() throws ApplicationSettingsException {
+        return Integer.valueOf(getSetting(Constants.TLS_CLIENT_TIMEOUT));
+    }
 }
diff --git a/custos-sharing-registry-service/pom.xml b/custos-sharing-registry-service/pom.xml
new file mode 100644
index 0000000..9637a81
--- /dev/null
+++ b/custos-sharing-registry-service/pom.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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">
+    <parent>
+        <artifactId>custos</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-sharing-registry-service</artifactId>
+    <packaging>pom</packaging>
+
+    <modules>
+        <module>sharing-registry-distribution</module>
+        <module>sharing-registry-server</module>
+        <module>sharing-registry-stubs</module>
+    </modules>
+
+</project>
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-distribution/pom.xml b/custos-sharing-registry-service/sharing-registry-distribution/pom.xml
new file mode 100644
index 0000000..3e709f6
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-distribution/pom.xml
@@ -0,0 +1,87 @@
+<?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">
+    <parent>
+        <artifactId>custos-sharing-registry-service</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-sharing-registry-distribution</artifactId>
+    <packaging>jar</packaging>
+    <name>Sharing Registry Distribution</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.10</version>
+        </dependency>
+        <dependency>
+            <groupId>net.sf.dozer</groupId>
+            <artifactId>dozer</artifactId>
+            <version>5.4.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.openjpa</groupId>
+            <artifactId>openjpa</artifactId>
+            <version>${openjpa.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>${mysql.connector.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.thrift</groupId>
+            <artifactId>libthrift</artifactId>
+            <version>${thrift.version}</version>
+        </dependency>
+    </dependencies>
+
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <version>${maven.assembly.plugin}</version>
+                <executions>
+                    <execution>
+                        <id>distribution-package</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <descriptors>
+                                <descriptor>src/main/assembly/bin-assembly.xml</descriptor>
+                            </descriptors>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/custos-sharing-registry-service/sharing-registry-distribution/src/main/assembly/bin-assembly.xml b/custos-sharing-registry-service/sharing-registry-distribution/src/main/assembly/bin-assembly.xml
new file mode 100644
index 0000000..038a065
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-distribution/src/main/assembly/bin-assembly.xml
@@ -0,0 +1,75 @@
+<!--
+
+
+    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.
+
+-->
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
+          http://maven.apache.org/xsd/assembly-1.1.2.xsd">
+    <id>bin</id>
+    <includeBaseDirectory>true</includeBaseDirectory>
+    <baseDirectory>sharing-registry</baseDirectory>
+    <formats>
+        <format>tar.gz</format>
+    </formats>
+
+    <fileSets>
+        <fileSet>
+            <directory>src/main/resources/bin</directory>
+            <outputDirectory>bin</outputDirectory>
+            <includes>
+                <include>*.sh</include>
+            </includes>
+            <fileMode>755</fileMode>
+        </fileSet>
+
+        <!-- ********************** copy airavata-server.properties and key stores ********************** -->
+        <fileSet>
+            <directory>../../configuration/server/src/main/resources/</directory>
+            <outputDirectory>bin</outputDirectory>
+            <includes>
+                <include>airavata-server.properties</include>
+                <include>log4j.properties</include>
+                <include>airavata.jks</include>
+                <include>client_truststore.jks</include>
+            </includes>
+        </fileSet>
+
+        <!-- ********************** copy database scripts ********************** -->
+        <fileSet>
+            <directory>../sharing-registry-server/src/main/resources/
+            </directory>
+            <outputDirectory>bin/database_scripts
+            </outputDirectory>
+            <includes>
+                <include>*sql*</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+
+    <dependencySets>
+        <dependencySet>
+            <outputDirectory>/lib</outputDirectory>
+            <includes>
+                <include>*:jar:*</include>
+            </includes>
+        </dependencySet>
+    </dependencySets>
+</assembly>
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-distribution/src/main/resources/bin/setenv.sh b/custos-sharing-registry-service/sharing-registry-distribution/src/main/resources/bin/setenv.sh
new file mode 100644
index 0000000..1e5475d
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-distribution/src/main/resources/bin/setenv.sh
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+# 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.
+
+# Get standard environment variables
+# if JAVA_HOME is not set we're not happy
+if [ -z "$JAVA_HOME" ]; then
+  echo "You must set the JAVA_HOME variable before running sharing-registry scripts."
+  exit 1
+fi
+
+# OS specific support.  $var _must_ be set to either true or false.
+cygwin=false
+os400=false
+case "`uname`" in
+CYGWIN*) cygwin=true;;
+OS400*) os400=true;;
+esac
+
+# resolve links - $0 may be a softlink
+PRG="$0"
+
+while [ -h "$PRG" ]; do
+  ls=`ls -ld "$PRG"`
+  link=`expr "$ls" : '.*-> \(.*\)$'`
+  if expr "$link" : '.*/.*' > /dev/null; then
+    PRG="$link"
+  else
+    PRG=`dirname "$PRG"`/"$link"
+  fi
+done
+
+PRGDIR=`dirname "$PRG"`
+
+# Only set SHARING_REGISTRY_HOME if not already set
+[ -z "$SHARING_REGISTRY_HOME" ] && SHARING_REGISTRY_HOME=`cd "$PRGDIR/.." ; pwd`
+
+SHARING_REGISTRY_CLASSPATH=""
+
+for f in "$SHARING_REGISTRY_HOME"/lib/*.jar
+do
+  SHARING_REGISTRY_CLASSPATH="$SHARING_REGISTRY_CLASSPATH":$f
+done
+
+export SHARING_REGISTRY_HOME
+export SHARING_REGISTRY_CLASSPATH
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-distribution/src/main/resources/bin/sharing-registry.sh b/custos-sharing-registry-service/sharing-registry-distribution/src/main/resources/bin/sharing-registry.sh
new file mode 100644
index 0000000..07c7612
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-distribution/src/main/resources/bin/sharing-registry.sh
@@ -0,0 +1,90 @@
+#!/bin/bash
+
+# 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.
+
+. `dirname $0`/setenv.sh
+cd $SHARING_REGISTRY_HOME/bin
+
+IS_DAEMON_MODE=false
+SHARING_REGISTRY_COMMAND=""
+STOP=false
+FORCE=false
+JAVA_OPTS=""
+
+for var in "$@"
+do
+    case $var in
+    -xdebug)
+        	AIRAVATA_COMMAND="${AIRAVATA_COMMAND}"
+            JAVA_OPTS="$JAVA_OPTS -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,address=8000"
+            shift
+        ;;
+	start)
+	    IS_DAEMON_MODE=true
+            shift
+        ;;
+	stop)
+	    STOP=true
+	    SHARING_REGISTRY_COMMAND="$
+	    SHARING_REGISTRY_COMMAND $var"
+            shift
+        ;;
+        -h)
+            echo "Usage: sharing-registry.sh [command-options]"
+            echo "command options:"
+	    echo "  start              Start server in daemon mode"
+	    echo "  stop               Stop server."
+	    echo "  -xdebug			   Start Sharing Registry Server under JPDA debugger"
+	    echo "  -h                 Display this help and exit"
+	        shift
+            exit 0
+        ;;
+	*)
+	    SHARING_REGISTRY_COMMAND="$SHARING_REGISTRY_COMMAND $var"
+            shift
+    esac
+done
+
+if $STOP;
+then
+	for f in `find . -name "server_start_*"`; do
+		IFS='_' read -a f_split <<< "$f"
+		echo "Found process file : $f"
+		echo -n "    Sending kill signals to process ${f_split[2]}..."
+		out=`kill -9 ${f_split[2]} 2>&1`
+		if [ -z "$out" ]; then
+		    echo "done"
+		else
+		    echo "failed (REASON: $out)"
+		fi
+		echo -n "    Removing process file..."
+		out=`rm $f 2>&1`
+		if [ -z "$out" ]; then
+		    echo "done"
+		else
+		    echo "failed (REASON: $out)"
+		fi
+	done
+else
+	if $IS_DAEMON_MODE ; then
+		echo "Starting Sharing Registry Server in daemon mode..."
+		$JAVA_HOME/bin/java ${JAVA_OPTS} -classpath "$SHARING_REGISTRY_CLASSPATH"  org.apache.airavata.sharing.registry.server.ServerMain $* > /dev/null 2>&1 &
+	else
+		$JAVA_HOME/bin/java ${JAVA_OPTS} -classpath "$SHARING_REGISTRY_CLASSPATH"  org.apache.airavata.sharing.registry.server.ServerMain $*
+	fi
+fi
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/pom.xml b/custos-sharing-registry-service/sharing-registry-server/pom.xml
new file mode 100644
index 0000000..d530cd7
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/pom.xml
@@ -0,0 +1,130 @@
+<?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">
+    <parent>
+        <artifactId>custos-sharing-registry-service</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <relativePath>../pom.xml</relativePath>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-sharing-registry-server</artifactId>
+    <packaging>jar</packaging>
+    <name>Sharing Registry Server</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.10</version>
+        </dependency>
+        <dependency>
+            <groupId>net.sf.dozer</groupId>
+            <artifactId>dozer</artifactId>
+            <version>5.4.0</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-log4j12</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.openjpa</groupId>
+            <artifactId>openjpa</artifactId>
+            <version>${openjpa.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>${mysql.connector.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.thrift</groupId>
+            <artifactId>libthrift</artifactId>
+            <version>${thrift.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.databene</groupId>
+            <artifactId>contiperf</artifactId>
+            <version>2.3.4</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-commons</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-sharing-registry-stubs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.5.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>2.3.2</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.openjpa</groupId>
+                <artifactId>openjpa-maven-plugin</artifactId>
+                <version>${openjpa.version}</version>
+                <configuration>
+                    <includes>**/entities/*.class</includes>
+                    <excludes>**/entities/XML*.class</excludes>
+                    <addDefaultConstructor>true</addDefaultConstructor>
+                    <enforcePropertyRestrictions>true</enforcePropertyRestrictions>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>enhancer</id>
+                        <phase>process-classes</phase>
+                        <goals>
+                            <goal>enhance</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/DomainEntity.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/DomainEntity.java
new file mode 100644
index 0000000..620c9b4
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/DomainEntity.java
@@ -0,0 +1,116 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "DOMAIN", schema = "" )
+public class DomainEntity {
+    private final static Logger logger = LoggerFactory.getLogger(DomainEntity.class);
+    private String domainId;
+    private String name;
+    private String description;
+    private Long createdTime;
+    private Long updatedTime;
+
+    @Id
+    @Column(name = "DOMAIN_ID")
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Basic
+    @Column(name = "NAME")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Basic
+    @Column(name = "DESCRIPTION")
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @Basic
+    @Column(name = "CREATED_TIME")
+    public Long getCreatedTime() {
+        return createdTime;
+    }
+
+    public void setCreatedTime(Long createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    @Basic
+    @Column(name = "UPDATED_TIME")
+    public Long getUpdatedTime() {
+        return updatedTime;
+    }
+
+    public void setUpdatedTime(Long updatedTime) {
+        this.updatedTime = updatedTime;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        DomainEntity that = (DomainEntity) o;
+
+        if (getDomainId() != null ? !getDomainId().equals(that.getDomainId()) : that.getDomainId() != null)
+            return false;
+        if (getName() != null ? !getName().equals(that.getName()) : that.getName() != null) return false;
+        if (getDescription() != null ? !getDescription().equals(that.getDescription()) : that.getDescription() != null)
+            return false;
+        if (getCreatedTime() != null ? !getCreatedTime().equals(that.getCreatedTime()) : that.getCreatedTime() != null)
+            return false;
+        if (getUpdatedTime() != null ? !getUpdatedTime().equals(that.getUpdatedTime()) : that.getUpdatedTime() != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getDomainId() != null ? getDomainId().hashCode() : 0;
+        result = 31 * result + (getName() != null ? getName().hashCode() : 0);
+        result = 31 * result + (getDescription() != null ? getDescription().hashCode() : 0);
+        result = 31 * result + (getCreatedTime() != null ? getCreatedTime().hashCode() : 0);
+        result = 31 * result + (getUpdatedTime() != null ? getUpdatedTime().hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/EntityEntity.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/EntityEntity.java
new file mode 100644
index 0000000..a87fbf4
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/EntityEntity.java
@@ -0,0 +1,219 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.*;
+import java.nio.ByteBuffer;
+
+@Entity
+@Table(name = "ENTITY", schema = "")
+@IdClass(EntityPK.class)
+public class EntityEntity {
+    private final static Logger logger = LoggerFactory.getLogger(EntityEntity.class);
+    private String entityId;
+    private String domainId;
+    private String entityTypeId;
+    private String ownerId;
+    private String parentEntityId;
+    private String name;
+    private String description;
+    private ByteBuffer binaryData;
+    private String fullText;
+    private Long originalEntityCreationTime;
+    private Long sharedCount;
+    private Long createdTime;
+    private Long updatedTime;
+
+    @Id
+    @Column(name = "ENTITY_ID")
+    public String getEntityId() {
+        return entityId;
+    }
+
+    public void setEntityId(String entityId) {
+        this.entityId = entityId;
+    }
+
+    @Id
+    @Column(name = "DOMAIN_ID")
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Basic
+    @Column(name = "ENTITY_TYPE_ID")
+    public String getEntityTypeId() {
+        return entityTypeId;
+    }
+
+    public void setEntityTypeId(String entityTypeId) {
+        this.entityTypeId = entityTypeId;
+    }
+
+    @Basic
+    @Column(name = "OWNER_ID")
+    public String getOwnerId() {
+        return ownerId;
+    }
+
+    public void setOwnerId(String ownerId) {
+        this.ownerId = ownerId;
+    }
+
+    @Basic
+    @Column(name = "PARENT_ENTITY_ID")
+    public String getParentEntityId() {
+        return parentEntityId;
+    }
+
+    public void setParentEntityId(String parentEntityId) {
+        this.parentEntityId = parentEntityId;
+    }
+
+    @Basic
+    @Column(name = "NAME")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Basic
+    @Column(name = "DESCRIPTION")
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @Lob
+    @Column(name="BINARY_DATA")
+    public ByteBuffer getBinaryData() {
+        return binaryData;
+    }
+
+    public void setBinaryData(ByteBuffer binaryData) {
+        this.binaryData = binaryData;
+    }
+
+    @Basic
+    @Column(name = "FULL_TEXT")
+    public String getFullText() {
+        return fullText;
+    }
+
+    public void setFullText(String fullText) {
+        this.fullText = fullText;
+    }
+
+    @Basic
+    @Column(name = "ORIGINAL_ENTITY_CREATION_TIME")
+    public Long getOriginalEntityCreationTime() {
+        return originalEntityCreationTime;
+    }
+
+    public void setOriginalEntityCreationTime(Long originalEntityCreationTime) {
+        this.originalEntityCreationTime = originalEntityCreationTime;
+    }
+
+    @Basic
+    @Column(name = "SHARED_COUNT")
+    public Long getSharedCount() {
+        return sharedCount;
+    }
+
+    public void setSharedCount(Long sharedCount) {
+        this.sharedCount = sharedCount;
+    }
+
+    @Basic
+    @Column(name = "CREATED_TIME")
+    public Long getCreatedTime() {
+        return createdTime;
+    }
+
+    public void setCreatedTime(Long createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    @Basic
+    @Column(name = "UPDATED_TIME")
+    public Long getUpdatedTime() {
+        return updatedTime;
+    }
+
+    public void setUpdatedTime(Long updatedTime) {
+        this.updatedTime = updatedTime;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        EntityEntity that = (EntityEntity) o;
+
+        if (getEntityId() != null ? !getEntityId().equals(that.getEntityId()) : that.getEntityId() != null)
+            return false;
+        if (getDomainId() != null ? !getDomainId().equals(that.getDomainId()) : that.getDomainId() != null)
+            return false;
+        if (getParentEntityId() != null ? !getParentEntityId().equals(that.getParentEntityId()) : that.getParentEntityId() != null)
+            return false;
+        if (getName() != null ? !getName().equals(that.getName()) : that.getName() != null) return false;
+        if (getDescription() != null ? !getDescription().equals(that.getDescription()) : that.getDescription() != null)
+            return false;
+        if (getBinaryData().equals(that.getBinaryData())) return false;
+        if (getFullText() != null ? !getFullText().equals(that.getFullText()) : that.getFullText() != null)
+            return false;
+        if (getOriginalEntityCreationTime() != null ? !getOriginalEntityCreationTime().equals(that.getOriginalEntityCreationTime())
+                : that.getOriginalEntityCreationTime() != null) return false;
+        if (getCreatedTime() != null ? !getCreatedTime().equals(that.getCreatedTime()) : that.getCreatedTime() != null)
+            return false;
+        if (getUpdatedTime() != null ? !getUpdatedTime().equals(that.getUpdatedTime()) : that.getUpdatedTime() != null)
+            return false;
+        if (getOwnerId() != null ? !getOwnerId().equals(that.getOwnerId()) : that.getOwnerId() != null) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getEntityId() != null ? getEntityId().hashCode() : 0;
+        result = 31 * result + (getName() != null ? getName().hashCode() : 0);
+        result = 31 * result + (getDescription() != null ? getDescription().hashCode() : 0);
+        result = 31 * result + (getBinaryData() != null ? getBinaryData().hashCode() : 0);
+        result = 31 * result + (getFullText() != null ? getFullText().hashCode() : 0);
+        result = 31 * result + (getOriginalEntityCreationTime() != null ? getOriginalEntityCreationTime().hashCode() : 0);
+        result = 31 * result + (getCreatedTime() != null ? getCreatedTime().hashCode() : 0);
+        result = 31 * result + (getUpdatedTime() != null ? getUpdatedTime().hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/EntityPK.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/EntityPK.java
new file mode 100644
index 0000000..9999743
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/EntityPK.java
@@ -0,0 +1,76 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+import java.io.Serializable;
+
+public class EntityPK implements Serializable {
+    private final static Logger logger = LoggerFactory.getLogger(EntityPK.class);
+    private String entityId;
+    private String domainId;
+
+
+    @Column(name = "ENTITY_ID")
+    @Id
+    public String getEntityId() {
+        return entityId;
+    }
+
+    public void setEntityId(String entityId) {
+        this.entityId = entityId;
+    }
+
+    @Column(name = "DOMAIN_ID")
+    @Id
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        EntityPK that = (EntityPK) o;
+
+        if (getDomainId() != null ? !getDomainId().equals(that.getDomainId()) : that.getDomainId() != null)
+            return false;
+        if (getEntityId() != null ? !getEntityId().equals(that.getEntityId()) : that.getEntityId() != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getDomainId() != null ? getDomainId().hashCode() : 0;
+        result = 31 * result + (getEntityId() != null ? getEntityId().hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/EntityTypeEntity.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/EntityTypeEntity.java
new file mode 100644
index 0000000..458a4a9
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/EntityTypeEntity.java
@@ -0,0 +1,130 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "ENTITY_TYPE", schema = "")
+@IdClass(EntityTypePK.class)
+public class EntityTypeEntity {
+    private final static Logger logger = LoggerFactory.getLogger(EntityTypeEntity.class);
+    private String entityTypeId;
+    private String domainId;
+    private String name;
+    private String description;
+    private Long createdTime;
+    private Long updatedTime;
+
+    @Id
+    @Column(name = "ENTITY_TYPE_ID")
+    public String getEntityTypeId() {
+        return entityTypeId;
+    }
+
+    public void setEntityTypeId(String entityTypeId) {
+        this.entityTypeId = entityTypeId;
+    }
+
+    @Id
+    @Column(name = "DOMAIN_ID")
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Basic
+    @Column(name = "NAME")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Basic
+    @Column(name = "DESCRIPTION")
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @Basic
+    @Column(name = "CREATED_TIME")
+    public Long getCreatedTime() {
+        return createdTime;
+    }
+
+    public void setCreatedTime(Long createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    @Basic
+    @Column(name = "UPDATED_TIME")
+    public Long getUpdatedTime() {
+        return updatedTime;
+    }
+
+    public void setUpdatedTime(Long updatedTime) {
+        this.updatedTime = updatedTime;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        EntityTypeEntity that = (EntityTypeEntity) o;
+
+        if (getEntityTypeId() != null ? !getEntityTypeId().equals(that.getEntityTypeId()) : that.getEntityTypeId() != null)
+            return false;
+        if (getDomainId() != null ? !getDomainId().equals(that.getDomainId()) : that.getDomainId() != null)
+            return false;
+        if (getName() != null ? !getName().equals(that.getName()) : that.getName() != null) return false;
+        if (getDescription() != null ? !getDescription().equals(that.getDescription()) : that.getDescription() != null)
+            return false;
+        if (getCreatedTime() != null ? !getCreatedTime().equals(that.getCreatedTime()) : that.getCreatedTime() != null)
+            return false;
+        if (getUpdatedTime() != null ? !getUpdatedTime().equals(that.getUpdatedTime()) : that.getUpdatedTime() != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getEntityTypeId() != null ? getEntityTypeId().hashCode() : 0;
+        result = 31 * result + (getName() != null ? getName().hashCode() : 0);
+        result = 31 * result + (getDescription() != null ? getDescription().hashCode() : 0);
+        result = 31 * result + (getCreatedTime() != null ? getCreatedTime().hashCode() : 0);
+        result = 31 * result + (getUpdatedTime() != null ? getUpdatedTime().hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/EntityTypePK.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/EntityTypePK.java
new file mode 100644
index 0000000..f162b3b
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/EntityTypePK.java
@@ -0,0 +1,76 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+import java.io.Serializable;
+
+public class EntityTypePK implements Serializable {
+    private final static Logger logger = LoggerFactory.getLogger(EntityTypePK.class);
+    private String entityTypeId;
+    private String domainId;
+
+
+    @Column(name = "ENTITY_TYPE_ID")
+    @Id
+    public String getEntityTypeId() {
+        return entityTypeId;
+    }
+
+    public void setEntityTypeId(String entityTypeId) {
+        this.entityTypeId = entityTypeId;
+    }
+
+    @Column(name = "DOMAIN_ID")
+    @Id
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        EntityTypePK that = (EntityTypePK) o;
+
+        if (getEntityTypeId() != null ? !getEntityTypeId().equals(that.getEntityTypeId()) : that.getEntityTypeId() != null)
+            return false;
+        if (getDomainId() != null ? !getDomainId().equals(that.getDomainId()) : that.getDomainId() != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getEntityTypeId() != null ? getEntityTypeId().hashCode() : 0;
+        result = 31 * result + (getDomainId() != null ? getDomainId().hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/GroupAdminEntity.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/GroupAdminEntity.java
new file mode 100644
index 0000000..26fe095
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/GroupAdminEntity.java
@@ -0,0 +1,80 @@
+package org.apache.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "GROUP_ADMIN", schema = "")
+@IdClass(GroupAdminPK.class)
+public class GroupAdminEntity {
+    private final static Logger logger = LoggerFactory.getLogger(GroupAdminEntity.class);
+    private String groupId;
+    private String domainId;
+    private String adminId;
+    private UserGroupEntity userGroup;
+
+    @Id
+    @Column(name = "GROUP_ID")
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    @Id
+    @Column(name = "DOMAIN_ID")
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Id
+    @Column(name = "ADMIN_ID")
+    public String getAdminId() {
+        return adminId;
+    }
+
+    public void setAdminId(String adminId) {
+        this.adminId = adminId;
+    }
+
+    @ManyToOne(targetEntity = UserGroupEntity.class, cascade = CascadeType.MERGE)
+    @JoinColumns({
+            @JoinColumn(name="GROUP_ID", referencedColumnName="GROUP_ID"),
+            @JoinColumn(name="DOMAIN_ID", referencedColumnName="DOMAIN_ID")
+    })
+    public UserGroupEntity getUserGroup() {
+        return userGroup;
+    }
+
+    public void setUserGroup(UserGroupEntity userGroup) {
+        this.userGroup = userGroup;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        GroupAdminEntity that = (GroupAdminEntity) o;
+
+        if (!getGroupId().equals(that.getGroupId())) return false;
+        if (!getDomainId().equals(that.getDomainId())) return false;
+        return getAdminId().equals(that.getAdminId());
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getGroupId().hashCode();
+        result = 31 * result + getDomainId().hashCode();
+        result = 31 * result + getAdminId().hashCode();
+        return result;
+    }
+}
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/GroupAdminPK.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/GroupAdminPK.java
new file mode 100644
index 0000000..a036cf9
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/GroupAdminPK.java
@@ -0,0 +1,66 @@
+package org.apache.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+import java.io.Serializable;
+
+public class GroupAdminPK implements Serializable{
+
+    private final static Logger logger = LoggerFactory.getLogger(GroupAdminPK.class);
+    private String groupId;
+    private String domainId;
+    private String adminId;
+
+    @Id
+    @Column(name = "GROUP_ID")
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    @Id
+    @Column(name = "DOMAIN_ID")
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Id
+    @Column(name = "ADMIN_ID")
+    public String getAdminId() {
+        return adminId;
+    }
+
+    public void setAdminId(String adminId) {
+        this.adminId = adminId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        GroupAdminPK groupAdminPK = (GroupAdminPK) o;
+
+        if (!getGroupId().equals(groupAdminPK.getGroupId())) return false;
+        if (!getDomainId().equals(groupAdminPK.getDomainId())) return false;
+        return getAdminId().equals(groupAdminPK.getAdminId());
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getGroupId().hashCode();
+        result = 31 * result + getDomainId().hashCode();
+        result = 31 * result + getAdminId().hashCode();
+        return result;
+    }
+}
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/GroupMembershipEntity.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/GroupMembershipEntity.java
new file mode 100644
index 0000000..692411d
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/GroupMembershipEntity.java
@@ -0,0 +1,126 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "GROUP_MEMBERSHIP", schema = "")
+@IdClass(GroupMembershipPK.class)
+public class GroupMembershipEntity {
+    private final static Logger logger = LoggerFactory.getLogger(GroupMembershipEntity.class);
+    private String parentId;
+    private String childId;
+    private String childType;
+    private String domainId;
+    private Long createdTime;
+    private Long updatedTime;
+
+    @Id
+    @Column(name = "PARENT_ID")
+    public String getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(String parentId) {
+        this.parentId = parentId;
+    }
+
+    @Id
+    @Column(name = "CHILD_ID")
+    public String getChildId() {
+        return childId;
+    }
+
+    public void setChildId(String childId) {
+        this.childId = childId;
+    }
+
+    @Id
+    @Column(name = "DOMAIN_ID")
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Basic
+    @Column(name = "CHILD_TYPE")
+    public String getChildType() {
+        return childType;
+    }
+
+    public void setChildType(String childType) {
+        this.childType = childType;
+    }
+
+    @Basic
+    @Column(name = "CREATED_TIME")
+    public Long getCreatedTime() {
+        return createdTime;
+    }
+
+    public void setCreatedTime(Long createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    @Basic
+    @Column(name = "UPDATED_TIME")
+    public Long getUpdatedTime() {
+        return updatedTime;
+    }
+
+    public void setUpdatedTime(Long updatedTime) {
+        this.updatedTime = updatedTime;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        GroupMembershipEntity that = (GroupMembershipEntity) o;
+
+        if (getParentId() != null ? !getParentId().equals(that.getParentId()) : that.getParentId() != null)
+            return false;
+        if (getChildId() != null ? !getChildId().equals(that.getChildId()) : that.getChildId() != null) return false;
+        if (getChildType() != null ? !getChildType().equals(that.getChildType()) : that.getChildType() != null)
+            return false;
+        if (getCreatedTime() != null ? !getCreatedTime().equals(that.getCreatedTime()) : that.getCreatedTime() != null)
+            return false;
+        if (getUpdatedTime() != null ? !getUpdatedTime().equals(that.getUpdatedTime()) : that.getUpdatedTime() != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getParentId() != null ? getParentId().hashCode() : 0;
+        result = 31 * result + (getChildId() != null ? getChildId().hashCode() : 0);
+        result = 31 * result + (getChildType() != null ? getChildType().hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/GroupMembershipPK.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/GroupMembershipPK.java
new file mode 100644
index 0000000..37c83c0
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/GroupMembershipPK.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.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+import java.io.Serializable;
+
+public class GroupMembershipPK implements Serializable {
+    private final static Logger logger = LoggerFactory.getLogger(GroupMembershipPK.class);
+    private String parentId;
+    private String childId;
+    private String domainId;
+
+    @Column(name = "PARENT_ID")
+    @Id
+    public String getParentId() {
+        return parentId;
+    }
+
+    public void setParentId(String parentId) {
+        this.parentId = parentId;
+    }
+
+    @Column(name = "CHILD_ID")
+    @Id
+    public String getChildId() {
+        return childId;
+    }
+
+    public void setChildId(String childId) {
+        this.childId = childId;
+    }
+
+    @Column(name = "DOMAIN_ID")
+    @Id
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        GroupMembershipPK that = (GroupMembershipPK) o;
+
+        if (getParentId() != null ? !getParentId().equals(that.getParentId()) : that.getParentId() != null)
+            return false;
+        if (getChildId() != null ? !getChildId().equals(that.getChildId()) : that.getChildId() != null) return false;
+        if (getDomainId() != null ? !getDomainId().equals(that.getDomainId()) : that.getDomainId() != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getParentId() != null ? getParentId().hashCode() : 0;
+        result = 31 * result + (getChildId() != null ? getChildId().hashCode() : 0);
+        result = 31 * result + (getDomainId() != null ? getDomainId().hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/PermissionTypeEntity.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/PermissionTypeEntity.java
new file mode 100644
index 0000000..53882c0
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/PermissionTypeEntity.java
@@ -0,0 +1,128 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "PERMISSION_TYPE", schema = "")
+@IdClass(PermissionTypePK.class)
+public class PermissionTypeEntity {
+    private final static Logger logger = LoggerFactory.getLogger(PermissionTypeEntity.class);
+    private String permissionTypeId;
+    private String domainId;
+    private String name;
+    private String description;
+    private Long createdTime;
+    private Long updatedTime;
+
+    @Id
+    @Column(name = "PERMISSION_TYPE_ID")
+    public String getPermissionTypeId() {
+        return permissionTypeId;
+    }
+
+    public void setPermissionTypeId(String permissionTypeId) {
+        this.permissionTypeId = permissionTypeId;
+    }
+
+    @Id
+    @Column(name = "DOMAIN_ID")
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Basic
+    @Column(name = "NAME")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+
+    @Basic
+    @Column(name = "DESCRIPTION")
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @Basic
+    @Column(name = "CREATED_TIME")
+    public Long getCreatedTime() {
+        return createdTime;
+    }
+
+    public void setCreatedTime(Long createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    @Basic
+    @Column(name = "UPDATED_TIME")
+    public Long getUpdatedTime() {
+        return updatedTime;
+    }
+
+    public void setUpdatedTime(Long updatedTime) {
+        this.updatedTime = updatedTime;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        PermissionTypeEntity that = (PermissionTypeEntity) o;
+
+        if (getPermissionTypeId() != null ? !getPermissionTypeId().equals(that.getPermissionTypeId()) : that.getPermissionTypeId() != null)
+            return false;
+        if (getDomainId() != null ? !getDomainId().equals(that.getDomainId()) : that.getDomainId() != null)
+            return false;
+        if (getName() != null ? !getName().equals(that.getName()) : that.getName() != null) return false;
+        if (getCreatedTime() != null ? !getCreatedTime().equals(that.getCreatedTime()) : that.getCreatedTime() != null)
+            return false;
+        if (getUpdatedTime() != null ? !getUpdatedTime().equals(that.getUpdatedTime()) : that.getUpdatedTime() != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getPermissionTypeId() != null ? getPermissionTypeId().hashCode() : 0;
+        result = 31 * result + (getName() != null ? getName().hashCode() : 0);
+        result = 31 * result + (getCreatedTime() != null ? getCreatedTime().hashCode() : 0);
+        result = 31 * result + (getUpdatedTime() != null ? getUpdatedTime().hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/PermissionTypePK.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/PermissionTypePK.java
new file mode 100644
index 0000000..836316f
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/PermissionTypePK.java
@@ -0,0 +1,76 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+import java.io.Serializable;
+
+public class PermissionTypePK implements Serializable {
+    private final static Logger logger = LoggerFactory.getLogger(PermissionTypePK.class);
+    private String permissionTypeId;
+    private String domainId;
+
+
+    @Column(name = "PERMISSION_TYPE_ID")
+    @Id
+    public String getPermissionTypeId() {
+        return permissionTypeId;
+    }
+
+    public void setPermissionTypeId(String permissionTypeId) {
+        this.permissionTypeId = permissionTypeId;
+    }
+
+    @Column(name = "DOMAIN_ID")
+    @Id
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        PermissionTypePK that = (PermissionTypePK) o;
+
+        if (getPermissionTypeId() != null ? !getPermissionTypeId().equals(that.getPermissionTypeId()) : that.getPermissionTypeId() != null)
+            return false;
+        if (getDomainId() != null ? !getDomainId().equals(that.getDomainId()) : that.getDomainId() != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getPermissionTypeId() != null ? getPermissionTypeId().hashCode() : 0;
+        result = 31 * result + (getDomainId() != null ? getDomainId().hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/SharingEntity.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/SharingEntity.java
new file mode 100644
index 0000000..f52f574
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/SharingEntity.java
@@ -0,0 +1,149 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "SHARING", schema = "")
+@IdClass(SharingPK.class)
+public class SharingEntity {
+    private final static Logger logger = LoggerFactory.getLogger(SharingEntity.class);
+    private String permissionTypeId;
+    private String entityId;
+    private String groupId;
+    private String domainId;
+    private String sharingType;
+    private String inheritedParentId;
+    private Long createdTime;
+    private Long updatedTime;
+
+    @Id
+    @Column(name = "PERMISSION_TYPE_ID")
+    public String getPermissionTypeId() {
+        return permissionTypeId;
+    }
+
+    public void setPermissionTypeId(String permissionTypeId) {
+        this.permissionTypeId = permissionTypeId;
+    }
+
+    @Id
+    @Column(name = "ENTITY_ID")
+    public String getEntityId() {
+        return entityId;
+    }
+
+    public void setEntityId(String entityId) {
+        this.entityId = entityId;
+    }
+
+    @Id
+    @Column(name = "GROUP_ID")
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+
+    @Id
+    @Column(name = "INHERITED_PARENT_ID")
+    public String getInheritedParentId() {
+        return inheritedParentId;
+    }
+
+    public void setInheritedParentId(String inheritedParentId) {
+        this.inheritedParentId = inheritedParentId;
+    }
+
+    @Id
+    @Column(name = "DOMAIN_ID")
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Basic
+    @Column(name = "SHARING_TYPE")
+    public String getSharingType() {
+        return sharingType;
+    }
+
+    public void setSharingType(String sharingType) {
+        this.sharingType = sharingType;
+    }
+
+    @Basic
+    @Column(name = "CREATED_TIME")
+    public Long getCreatedTime() {
+        return createdTime;
+    }
+
+    public void setCreatedTime(Long createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    @Basic
+    @Column(name = "UPDATED_TIME")
+    public Long getUpdatedTime() {
+        return updatedTime;
+    }
+
+    public void setUpdatedTime(Long updatedTime) {
+        this.updatedTime = updatedTime;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        SharingEntity that = (SharingEntity) o;
+
+        if (getPermissionTypeId() != null ? !getPermissionTypeId().equals(that.getPermissionTypeId()) : that.getPermissionTypeId() != null)
+            return false;
+        if (getEntityId() != null ? !getEntityId().equals(that.getEntityId()) : that.getEntityId() != null)
+            return false;
+        if (getGroupId() != null ? !getGroupId().equals(that.getGroupId()) : that.getGroupId() != null) return false;
+        if (getCreatedTime() != null ? !getCreatedTime().equals(that.getCreatedTime()) : that.getCreatedTime() != null)
+            return false;
+        if (getUpdatedTime() != null ? !getUpdatedTime().equals(that.getUpdatedTime()) : that.getUpdatedTime() != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getPermissionTypeId() != null ? getPermissionTypeId().hashCode() : 0;
+        result = 31 * result + (getEntityId() != null ? getEntityId().hashCode() : 0);
+        result = 31 * result + (getGroupId() != null ? getGroupId().hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/SharingPK.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/SharingPK.java
new file mode 100644
index 0000000..506b486
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/SharingPK.java
@@ -0,0 +1,116 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+import java.io.Serializable;
+
+public class SharingPK implements Serializable {
+    private final static Logger logger = LoggerFactory.getLogger(SharingPK.class);
+    private String permissionTypeId;
+    private String entityId;
+    private String groupId;
+    private String inheritedParentId;
+    private String domainId;
+
+    @Column(name = "PERMISSION_TYPE_ID")
+    @Id
+    public String getPermissionTypeId() {
+        return permissionTypeId;
+    }
+
+    public void setPermissionTypeId(String permissionTypeId) {
+        this.permissionTypeId = permissionTypeId;
+    }
+
+    @Column(name = "ENTITY_ID")
+    @Id
+    public String getEntityId() {
+        return entityId;
+    }
+
+    public void setEntityId(String entityId) {
+        this.entityId = entityId;
+    }
+
+    @Column(name = "GROUP_ID")
+    @Id
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    @Column(name = "INHERITED_PARENT_ID")
+    @Id
+    public String getInheritedParentId() {
+        return inheritedParentId;
+    }
+
+    public void setInheritedParentId(String inheritedParentId) {
+        this.inheritedParentId = inheritedParentId;
+    }
+
+    @Column(name = "DOMAIN_ID")
+    @Id
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        SharingPK that = (SharingPK) o;
+
+        if (getPermissionTypeId() != null ? !getPermissionTypeId().equals(that.getPermissionTypeId()) : that.getPermissionTypeId() != null)
+            return false;
+        if (getEntityId() != null ? !getEntityId().equals(that.getEntityId()) : that.getEntityId() != null)
+            return false;
+        if (getGroupId() != null ? !getGroupId().equals(that.getGroupId()) : that.getGroupId() != null) return false;
+        if (getInheritedParentId() != null ? !getInheritedParentId().equals(that.getInheritedParentId()) : that.getInheritedParentId() != null)
+            return false;
+        if (getDomainId() != null ? !getDomainId().equals(that.getDomainId()) : that.getDomainId() != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getPermissionTypeId() != null ? getPermissionTypeId().hashCode() : 0;
+        result = 31 * result + (getEntityId() != null ? getEntityId().hashCode() : 0);
+        result = 31 * result + (getGroupId() != null ? getGroupId().hashCode() : 0);
+        result = 31 * result + (getInheritedParentId() != null ? getInheritedParentId().hashCode() : 0);
+        result = 31 * result + (getDomainId() != null ? getDomainId().hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/UserEntity.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/UserEntity.java
new file mode 100644
index 0000000..25fd4a5
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/UserEntity.java
@@ -0,0 +1,161 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.*;
+import java.nio.ByteBuffer;
+
+@Entity
+@Table(name = "SHARING_USER", schema = "") // USER is a reserved term in derby
+@IdClass(UserPK.class)
+public class UserEntity {
+    private final static Logger logger = LoggerFactory.getLogger(UserEntity.class);
+    private String userId;
+    private String domainId;
+    private String userName;
+    private String firstName;
+    private String lastName;
+    private String email;
+    private ByteBuffer icon;
+    private Long createdTime;
+    private Long updatedTime;
+
+    @Id
+    @Column(name = "USER_ID")
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    @Id
+    @Column(name = "DOMAIN_ID")
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Basic
+    @Column(name = "USER_NAME")
+    public String getUserName() {
+        return userName;
+    }
+
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+
+    @Basic
+    @Column(name = "FIRST_NAME")
+    public String getFirstName() {
+        return firstName;
+    }
+
+    public void setFirstName(String firstName) {
+        this.firstName = firstName;
+    }
+
+    @Basic
+    @Column(name = "LAST_NAME")
+    public String getLastName() {
+        return lastName;
+    }
+
+    public void setLastName(String lastName) {
+        this.lastName = lastName;
+    }
+
+    @Basic
+    @Column(name = "EMAIL")
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    @Lob
+    @Column(name = "ICON")
+    public ByteBuffer getIcon() {
+        return icon;
+    }
+
+    public void setIcon(ByteBuffer icon) {
+        this.icon = icon;
+    }
+
+    @Basic
+    @Column(name = "CREATED_TIME")
+    public Long getCreatedTime() {
+        return createdTime;
+    }
+
+    public void setCreatedTime(Long createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    @Basic
+    @Column(name = "UPDATED_TIME")
+    public Long getUpdatedTime() {
+        return updatedTime;
+    }
+
+    public void setUpdatedTime(Long updatedTime) {
+        this.updatedTime = updatedTime;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        UserEntity that = (UserEntity) o;
+
+        if (getUserId() != null ? !getUserId().equals(that.getUserId()) : that.getUserId() != null) return false;
+        if (getDomainId() != null ? !getDomainId().equals(that.getDomainId()) : that.getDomainId() != null)
+            return false;
+        if (getUserName() != null ? !getUserName().equals(that.getUserName()) : that.getUserName() != null)
+            return false;
+        if (getCreatedTime() != null ? !getCreatedTime().equals(that.getCreatedTime()) : that.getCreatedTime() != null)
+            return false;
+        if (getUpdatedTime() != null ? !getUpdatedTime().equals(that.getUpdatedTime()) : that.getUpdatedTime() != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getUserId() != null ? getUserId().hashCode() : 0;
+        result = 31 * result + (getUserName() != null ? getUserName().hashCode() : 0);
+        result = 31 * result + (getCreatedTime() != null ? getCreatedTime().hashCode() : 0);
+        result = 31 * result + (getUpdatedTime() != null ? getUpdatedTime().hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/UserGroupEntity.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/UserGroupEntity.java
new file mode 100644
index 0000000..9d8a3ea
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/UserGroupEntity.java
@@ -0,0 +1,178 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Entity
+@Table(name = "USER_GROUP", schema = "")
+@IdClass(UserGroupPK.class)
+public class UserGroupEntity {
+    private final static Logger logger = LoggerFactory.getLogger(UserGroupEntity.class);
+    private String groupId;
+    private String domainId;
+    private String name;
+    private String description;
+    private String ownerId;
+    private String groupType;
+    private String groupCardinality;
+    private Long createdTime;
+    private Long updatedTime;
+    private List<GroupAdminEntity> groupAdmins;
+
+    @Id
+    @Column(name = "GROUP_ID")
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    @Id
+    @Column(name = "DOMAIN_ID")
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Basic
+    @Column(name = "OWNER_ID")
+    public String getOwnerId() {
+        return ownerId;
+    }
+
+    public void setOwnerId(String ownerId) {
+        this.ownerId = ownerId;
+    }
+
+    @Basic
+    @Column(name = "NAME")
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Basic
+    @Column(name = "DESCRIPTION")
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    @Basic
+    @Column(name = "GROUP_CARDINALITY")
+    public String getGroupCardinality() {
+        return groupCardinality;
+    }
+
+    public void setGroupCardinality(String groupCardinality) {
+        this.groupCardinality = groupCardinality;
+    }
+
+    @Basic
+    @Column(name = "GROUP_TYPE")
+    public String getGroupType() {
+        return groupType;
+    }
+
+    public void setGroupType(String type) {
+        this.groupType = type;
+    }
+
+    @Basic
+    @Column(name = "CREATED_TIME")
+    public Long getCreatedTime() {
+        return createdTime;
+    }
+
+    public void setCreatedTime(Long createdTime) {
+        this.createdTime = createdTime;
+    }
+
+    @Basic
+    @Column(name = "UPDATED_TIME")
+    public Long getUpdatedTime() {
+        return updatedTime;
+    }
+
+    public void setUpdatedTime(Long updatedTime) {
+        this.updatedTime = updatedTime;
+    }
+
+    @OneToMany(targetEntity = GroupAdminEntity.class, cascade = CascadeType.ALL,
+            mappedBy = "userGroup", fetch = FetchType.EAGER)
+    public List<GroupAdminEntity> getGroupAdmins() {
+        return groupAdmins;
+    }
+
+    public void setGroupAdmins(List<GroupAdminEntity> groupAdmins) {
+        this.groupAdmins = groupAdmins;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        UserGroupEntity that = (UserGroupEntity) o;
+
+        if (getGroupId() != null ? !getGroupId().equals(that.getGroupId()) : that.getGroupId() != null) return false;
+        if (getDomainId() != null ? !getDomainId().equals(that.getDomainId()) : that.getDomainId() != null)
+            return false;
+        if (getOwnerId() != null ? !getOwnerId().equals(that.getOwnerId()) : that.getOwnerId() != null) return false;
+        if (getName() != null ? !getName().equals(that.getName()) : that.getName() != null) return false;
+        if (getDescription() != null ? !getDescription().equals(that.getDescription()) : that.getDescription() != null)
+            return false;
+        if (getGroupType() != null ? !getGroupType().equals(that.getGroupType()) : that.getGroupType() != null)
+            return false;
+        if (getCreatedTime() != null ? !getCreatedTime().equals(that.getCreatedTime()) : that.getCreatedTime() != null)
+            return false;
+        if (getUpdatedTime() != null ? !getUpdatedTime().equals(that.getUpdatedTime()) : that.getUpdatedTime() != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getGroupId() != null ? getGroupId().hashCode() : 0;
+        result = 31 * result + (getName() != null ? getName().hashCode() : 0);
+        result = 31 * result + (getDescription() != null ? getDescription().hashCode() : 0);
+        result = 31 * result + (getGroupType() != null ? getGroupType().hashCode() : 0);
+        result = 31 * result + (getCreatedTime() != null ? getCreatedTime().hashCode() : 0);
+        result = 31 * result + (getUpdatedTime() != null ? getUpdatedTime().hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/UserGroupPK.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/UserGroupPK.java
new file mode 100644
index 0000000..dc12feb
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/UserGroupPK.java
@@ -0,0 +1,75 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+import java.io.Serializable;
+
+public class UserGroupPK implements Serializable {
+    private final static Logger logger = LoggerFactory.getLogger(UserGroupPK.class);
+    private String groupId;
+    private String domainId;
+
+    @Column(name = "GROUP_ID")
+    @Id
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    @Column(name = "DOMAIN_ID")
+    @Id
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        UserGroupPK that = (UserGroupPK) o;
+
+        if (getGroupId() != null ? !getGroupId().equals(that.getGroupId()) : that.getGroupId() != null)
+            return false;
+        if (getDomainId() != null ? !getDomainId().equals(that.getDomainId()) : that.getDomainId() != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getGroupId() != null ? getGroupId().hashCode() : 0;
+        result = 31 * result + (getDomainId() != null ? getDomainId().hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/UserPK.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/UserPK.java
new file mode 100644
index 0000000..9f68aa0
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/entities/UserPK.java
@@ -0,0 +1,75 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.entities;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.Column;
+import javax.persistence.Id;
+import java.io.Serializable;
+
+public class UserPK implements Serializable {
+    private final static Logger logger = LoggerFactory.getLogger(UserPK.class);
+    private String userId;
+    private String domainId;
+
+    @Column(name = "USER_ID")
+    @Id
+    public String getUserId() {
+        return userId;
+    }
+
+    public void setUserId(String userId) {
+        this.userId = userId;
+    }
+
+    @Column(name = "DOMAIN_ID")
+    @Id
+    public String getDomainId() {
+        return domainId;
+    }
+
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        UserPK that = (UserPK) o;
+
+        if (getUserId() != null ? !getUserId().equals(that.getUserId()) : that.getUserId() != null)
+            return false;
+        if (getDomainId() != null ? !getDomainId().equals(that.getDomainId()) : that.getDomainId() != null)
+            return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = getUserId() != null ? getUserId().hashCode() : 0;
+        result = 31 * result + (getDomainId() != null ? getDomainId().hashCode() : 0);
+        return result;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/AbstractRepository.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/AbstractRepository.java
new file mode 100644
index 0000000..3823faa
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/AbstractRepository.java
@@ -0,0 +1,168 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.repositories;
+
+import org.apache.custos.sharing.registry.db.utils.Committer;
+import org.apache.custos.sharing.registry.db.utils.DBConstants;
+import org.apache.custos.sharing.registry.db.utils.JPAUtils;
+import org.apache.custos.sharing.registry.db.utils.ObjectMapperSingleton;
+import org.apache.custos.sharing.registry.models.SharingRegistryException;
+import org.dozer.Mapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public abstract class AbstractRepository<T, E, Id> {
+    private final static Logger logger = LoggerFactory.getLogger(AbstractRepository.class);
+
+    private Class<T> thriftGenericClass;
+    private Class<E> dbEntityGenericClass;
+
+    public AbstractRepository(Class<T> thriftGenericClass, Class<E> dbEntityGenericClass){
+        this.thriftGenericClass = thriftGenericClass;
+        this.dbEntityGenericClass = dbEntityGenericClass;
+    }
+
+    public T create(T t) throws SharingRegistryException {
+        return update(t);
+    }
+
+    //FIXME do a bulk insert
+    public List<T> create(List<T> tList) throws SharingRegistryException {
+        return update(tList);
+    }
+
+    public  T update(T t) throws SharingRegistryException {
+        Mapper mapper = ObjectMapperSingleton.getInstance();
+        E entity = mapper.map(t, dbEntityGenericClass);
+        E persistedCopy = execute(entityManager -> entityManager.merge(entity));
+        return mapper.map(persistedCopy, thriftGenericClass);
+    }
+
+    //FIXME do a bulk update
+    public  List<T> update(List<T> tList) throws SharingRegistryException {
+        List<T> returnList = new ArrayList<>();
+        for(T temp : tList)
+            returnList.add(update(temp));
+        return returnList;
+    }
+
+    public boolean delete(Id id) throws SharingRegistryException {
+        execute(entityManager -> {
+             E entity = entityManager.find(dbEntityGenericClass, id);
+             entityManager.remove(entity);
+             return entity;
+         });
+        return true;
+    }
+
+    public boolean delete(List<Id> idList) throws SharingRegistryException {
+        for(Id id : idList)
+            delete(id);
+        return true;
+    }
+
+    public T get(Id id) throws SharingRegistryException {
+        E entity = execute(entityManager -> entityManager
+                .find(dbEntityGenericClass, id));
+        Mapper mapper = ObjectMapperSingleton.getInstance();
+        if(entity == null)
+            return null;
+        return mapper.map(entity, thriftGenericClass);
+    }
+
+    public boolean isExists(Id id) throws SharingRegistryException {
+        return get(id) != null;
+    }
+
+    public List<T> get(List<Id> idList) throws SharingRegistryException {
+        List<T> returnList = new ArrayList<>();
+        for(Id id : idList)
+            returnList.add(get(id));
+        return returnList;
+    }
+
+    public List<T> select(Map<String, String> filters, int offset, int limit) throws SharingRegistryException {
+        String query = "SELECT DISTINCT p from " + dbEntityGenericClass.getSimpleName() + " as p";
+        ArrayList<String> parameters = new ArrayList<>();
+        int parameterCount = 1;
+        if (filters != null && filters.size() != 0) {
+            query += " WHERE ";
+            for (String k : filters.keySet()) {
+                query += "p." + k + " = ?" + parameterCount + " AND ";
+                parameters.add(filters.get(k));
+                parameterCount++;
+            }
+            query = query.substring(0, query.length() - 5);
+        }
+
+        query += " ORDER BY p.createdTime DESC";
+        String queryString = query;
+        int newLimit = limit < 0 ? DBConstants.SELECT_MAX_ROWS: limit;
+        List resultSet = execute(entityManager -> {
+            javax.persistence.Query q = entityManager.createQuery(queryString);
+            for (int i = 0; i < parameters.size(); i++) {
+                q.setParameter(i + 1, parameters.get(i));
+            }
+            return q.setFirstResult(offset).setMaxResults(newLimit).getResultList();
+        });
+        Mapper mapper = ObjectMapperSingleton.getInstance();
+        List<T> gatewayList = new ArrayList<>();
+        resultSet.stream().forEach(rs -> gatewayList.add(mapper.map(rs, thriftGenericClass)));
+        return gatewayList;
+    }
+
+    public List<T> select(String queryString, Map<String,Object> queryParameters, int offset, int limit) throws SharingRegistryException {
+        int newLimit = limit < 0 ? DBConstants.SELECT_MAX_ROWS: limit;
+        List resultSet = execute(entityManager -> {
+            Query q =  entityManager.createQuery(queryString);
+            for(Map.Entry<String, Object> queryParam : queryParameters.entrySet()){
+                q.setParameter(queryParam.getKey(), queryParam.getValue());
+            }
+            return q.setFirstResult(offset).setMaxResults(newLimit).getResultList();
+        });
+        Mapper mapper = ObjectMapperSingleton.getInstance();
+        List<T> gatewayList = new ArrayList<>();
+        resultSet.stream().forEach(rs -> gatewayList.add(mapper.map(rs, thriftGenericClass)));
+        return gatewayList;
+    }
+
+    public <R> R execute(Committer<EntityManager, R> committer) throws SharingRegistryException {
+        EntityManager entityManager = JPAUtils.getEntityManager();
+        try {
+            entityManager.getTransaction().begin();
+            R r = committer.commit(entityManager);
+            entityManager.getTransaction().commit();
+            return r;
+        } finally {
+            if (entityManager.isOpen()) {
+                if (entityManager.getTransaction().isActive()) {
+                    entityManager.getTransaction().rollback();
+                }
+                entityManager.close();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/DomainRepository.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/DomainRepository.java
new file mode 100644
index 0000000..beb4be3
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/DomainRepository.java
@@ -0,0 +1,33 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.repositories;
+
+import org.apache.custos.sharing.registry.db.entities.DomainEntity;
+import org.apache.custos.sharing.registry.models.Domain;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DomainRepository extends AbstractRepository<Domain, DomainEntity, String> {
+    private final static Logger logger = LoggerFactory.getLogger(DomainRepository.class);
+
+    public DomainRepository(){
+        super(Domain.class, DomainEntity.class);
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/EntityRepository.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/EntityRepository.java
new file mode 100644
index 0000000..8c16ab1
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/EntityRepository.java
@@ -0,0 +1,173 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.repositories;
+
+import org.apache.custos.sharing.registry.db.entities.EntityEntity;
+import org.apache.custos.sharing.registry.db.entities.EntityPK;
+import org.apache.custos.sharing.registry.db.utils.DBConstants;
+import org.apache.custos.sharing.registry.db.utils.SharingRegistryJDBCConfig;
+import org.apache.custos.sharing.registry.models.*;
+
+import java.util.*;
+
+public class EntityRepository extends AbstractRepository<Entity, EntityEntity, EntityPK> {
+
+    public EntityRepository() {
+        super(Entity.class, EntityEntity.class);
+    }
+
+    public List<Entity> getChildEntities(String domainId, String parentId) throws SharingRegistryException {
+        HashMap<String, String> filters = new HashMap<>();
+        filters.put(DBConstants.EntityTable.DOMAIN_ID, domainId);
+        filters.put(DBConstants.EntityTable.PARENT_ENTITY_ID, parentId);
+        return select(filters, 0, -1);
+    }
+
+    //TODO Replace with prepared statements
+    public List<Entity> searchEntities(String domainId, List<String> groupIds, List<SearchCriteria> filters,
+                                       int offset, int limit) throws SharingRegistryException {
+        String groupIdString = "'";
+        for(String groupId : groupIds)
+            groupIdString += groupId + "','";
+        groupIdString = groupIdString.substring(0, groupIdString.length()-2);
+
+        String query = "SELECT ENTITY.* FROM ENTITY WHERE ENTITY.ENTITY_ID IN (SELECT DISTINCT E.ENTITY_ID FROM ENTITY AS E INNER JOIN SHARING AS S ON (E.ENTITY_ID=S.ENTITY_ID AND E.DOMAIN_ID=S.DOMAIN_ID) WHERE " +
+                "E.DOMAIN_ID = '" + domainId + "' AND " + "S.GROUP_ID IN(" + groupIdString + ") AND ";
+
+        for(SearchCriteria searchCriteria : filters){
+            if(searchCriteria.getSearchField().equals(EntitySearchField.NAME)){
+                if (searchCriteria.getSearchCondition() != null && searchCriteria.getSearchCondition().equals(SearchCondition.NOT)) {
+                    query += "E.NAME != '" + searchCriteria.getValue() + "' AND ";
+                } else {
+                    query += "E.NAME LIKE '%" + searchCriteria.getValue() + "%' AND ";
+                }
+            }else if(searchCriteria.getSearchField().equals(EntitySearchField.DESCRIPTION)){
+                query += "E.DESCRIPTION LIKE '%" + searchCriteria.getValue() + "%' AND ";
+            }else if(searchCriteria.getSearchField().equals(EntitySearchField.PERMISSION_TYPE_ID)){
+                if (searchCriteria.getSearchCondition() != null && searchCriteria.getSearchCondition().equals(SearchCondition.NOT)) {
+                    query += "S.PERMISSION_TYPE_ID != '" + searchCriteria.getValue() + "' AND ";
+                } else {
+                    query += "S.PERMISSION_TYPE_ID IN ('" + searchCriteria.getValue() + "', '"
+                            + (new PermissionTypeRepository()).getOwnerPermissionTypeIdForDomain(domainId) + "') AND ";
+                }
+            }else if(searchCriteria.getSearchField().equals(EntitySearchField.FULL_TEXT)){
+                if (new SharingRegistryJDBCConfig().getDriver().contains("derby")) {
+                    query += "E.FULL_TEXT LIKE '%" + searchCriteria.getValue() + "%' AND ";
+                } else {
+                    // FULL TEXT Search with Query Expansion
+                    String queryTerms = "";
+                    for (String word : searchCriteria.getValue().trim().replaceAll(" +", " ").split(" ")) {
+                        queryTerms += queryTerms + " +" + word;
+                    }
+                    queryTerms = queryTerms.trim();
+                    query += "MATCH(E.FULL_TEXT) AGAINST ('" + queryTerms + "' IN BOOLEAN MODE) AND ";
+                }
+            }else if(searchCriteria.getSearchField().equals(EntitySearchField.PARRENT_ENTITY_ID)){
+                if (searchCriteria.getSearchCondition() != null && searchCriteria.getSearchCondition().equals(SearchCondition.NOT)) {
+                    query += "E.PARENT_ENTITY_ID != '" + searchCriteria.getValue() + "' AND ";
+                } else {
+                    query += "E.PARENT_ENTITY_ID = '" + searchCriteria.getValue() + "' AND ";
+                }
+            }else if(searchCriteria.getSearchField().equals(EntitySearchField.OWNER_ID)){
+                if (searchCriteria.getSearchCondition() != null && searchCriteria.getSearchCondition().equals(SearchCondition.NOT)) {
+                    query += "E.OWNER_ID != '" + searchCriteria.getValue() + "' AND ";
+                } else {
+                    query += "E.OWNER_ID = '" + searchCriteria.getValue() + "' AND ";
+                }
+            } else if (searchCriteria.getSearchField().equals(EntitySearchField.ENTITY_TYPE_ID)) {
+                if (searchCriteria.getSearchCondition() != null && searchCriteria.getSearchCondition().equals(SearchCondition.NOT)) {
+                    query += "E.ENTITY_TYPE_ID != '" + searchCriteria.getValue() + "' AND ";
+                } else {
+                    query += "E.ENTITY_TYPE_ID = '" + searchCriteria.getValue() + "' AND ";
+                }
+            }else if(searchCriteria.getSearchField().equals(EntitySearchField.CREATED_TIME)){
+                if(searchCriteria.getSearchCondition().equals(SearchCondition.GTE)){
+                    query += "E.CREATED_TIME >= " + Long.parseLong(searchCriteria.getValue().trim()) + " AND ";
+                }else{
+                    query += "E.CREATED_TIME <= " + Long.parseLong(searchCriteria.getValue().trim()) + " AND ";
+                }
+            }else if(searchCriteria.getSearchField().equals(EntitySearchField.UPDATED_TIME)){
+                if(searchCriteria.getSearchCondition().equals(SearchCondition.GTE)){
+                    query += "E.UPDATED_TIME >= " + Long.parseLong(searchCriteria.getValue().trim()) + " AND ";
+                }else{
+                    query += "E.UPDATED_TIME <= " + Long.parseLong(searchCriteria.getValue().trim()) + " AND ";
+                }
+            } else if (searchCriteria.getSearchField().equals(EntitySearchField.SHARED_COUNT)) {
+                if (searchCriteria.getSearchCondition().equals(SearchCondition.GTE)) {
+                    query += "E.SHARED_COUNT >= " + Integer.parseInt(searchCriteria.getValue().trim()) + " AND ";
+                } else {
+                    query += "E.SHARED_COUNT <= " + Integer.parseInt(searchCriteria.getValue().trim()) + " AND ";
+                }
+            }
+        }
+
+        query = query.substring(0, query.length() - 5);
+        query += ") ORDER BY ENTITY.CREATED_TIME DESC";
+
+        final String nativeQuery = query;
+        int newLimit = limit < 0 ? DBConstants.SELECT_MAX_ROWS: limit;
+
+        List<Object[]> temp = execute(entityManager -> entityManager.createNativeQuery(nativeQuery).setFirstResult(offset)
+                .setMaxResults(newLimit).getResultList());
+        List<Entity> resultSet = new ArrayList<>();
+
+        HashMap<String, Object> keys = new HashMap<>();
+
+        temp.stream().forEach(rs->{
+            Entity entity = new Entity();
+            entity.setEntityId((String)(rs[0]));
+            entity.setDomainId((String) (rs[1]));
+            entity.setEntityTypeId((String) (rs[2]));
+            entity.setOwnerId((String) (rs[3]));
+            entity.setParentEntityId((String) (rs[4]));
+            entity.setName((String) (rs[5]));
+            entity.setDescription((String)(rs[6]));
+            entity.setBinaryData((byte[]) (rs[7]));
+            entity.setFullText((String) (rs[8]));
+            entity.setSharedCount((long) rs[9]);
+            entity.setOriginalEntityCreationTime((long) (rs[10]));
+            entity.setCreatedTime((long) (rs[11]));
+            entity.setUpdatedTime((long) (rs[12]));
+
+            //Removing duplicates. Another option is to change the query to remove duplicates.
+            if (!keys.containsKey(entity + domainId + "," + entity.getEntityId())) {
+                resultSet.add(entity);
+                keys.put(entity + domainId + "," + entity.getEntityId(), null);
+            }
+        });
+
+        return resultSet;
+    }
+
+    public String getSelectQuery(Map<String, String> filters){
+        String query = "SELECT p from " + EntityEntity.class.getSimpleName() + " as p";
+        if(filters != null && filters.size() != 0){
+            query += " WHERE ";
+            for(String k : filters.keySet()){
+                query += "p." + k + " = '" + filters.get(k) + "' AND ";
+            }
+            query = query.substring(0, query.length()-5);
+        }
+
+        query += " ORDER BY p."+DBConstants.EntityTable.ORIGINAL_ENTITY_CREATION_TIME+" DESC";
+
+        return query;
+    }
+}
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/EntityTypeRepository.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/EntityTypeRepository.java
new file mode 100644
index 0000000..8bbc083
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/EntityTypeRepository.java
@@ -0,0 +1,34 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.repositories;
+
+import org.apache.custos.sharing.registry.db.entities.EntityTypeEntity;
+import org.apache.custos.sharing.registry.db.entities.EntityTypePK;
+import org.apache.custos.sharing.registry.models.EntityType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EntityTypeRepository extends AbstractRepository<EntityType, EntityTypeEntity, EntityTypePK> {
+    private final static Logger logger = LoggerFactory.getLogger(EntityTypeRepository.class);
+
+    public EntityTypeRepository() {
+        super(EntityType.class, EntityTypeEntity.class);
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/GroupAdminRepository.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/GroupAdminRepository.java
new file mode 100644
index 0000000..a7b94a2
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/GroupAdminRepository.java
@@ -0,0 +1,17 @@
+package org.apache.custos.sharing.registry.db.repositories;
+
+import org.apache.custos.sharing.registry.db.entities.GroupAdminEntity;
+import org.apache.custos.sharing.registry.db.entities.GroupAdminPK;
+import org.apache.custos.sharing.registry.models.GroupAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GroupAdminRepository extends AbstractRepository<GroupAdmin, GroupAdminEntity, GroupAdminPK> {
+
+    private final static Logger logger = LoggerFactory.getLogger(GroupAdminRepository.class);
+
+    public GroupAdminRepository() {
+        super(GroupAdmin.class, GroupAdminEntity.class);
+    }
+
+}
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/GroupMembershipRepository.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/GroupMembershipRepository.java
new file mode 100644
index 0000000..a260400
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/GroupMembershipRepository.java
@@ -0,0 +1,104 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.repositories;
+
+import org.apache.custos.sharing.registry.db.entities.GroupMembershipEntity;
+import org.apache.custos.sharing.registry.db.entities.GroupMembershipPK;
+import org.apache.custos.sharing.registry.db.entities.UserEntity;
+import org.apache.custos.sharing.registry.db.entities.UserGroupEntity;
+import org.apache.custos.sharing.registry.db.utils.DBConstants;
+import org.apache.custos.sharing.registry.models.*;
+
+import java.util.*;
+
+public class GroupMembershipRepository extends AbstractRepository<GroupMembership, GroupMembershipEntity, GroupMembershipPK> {
+
+    public GroupMembershipRepository() {
+        super(GroupMembership.class, GroupMembershipEntity.class);
+    }
+
+    public List<User> getAllChildUsers(String domainId, String groupId) throws SharingRegistryException {
+        String queryString = "SELECT DISTINCT U FROM " + UserEntity.class.getSimpleName() + " U, " + GroupMembershipEntity.class.getSimpleName()
+                + " GM WHERE GM." + DBConstants.GroupMembershipTable.CHILD_ID + " = U." + DBConstants.UserTable.USER_ID + " AND " +
+                "GM." + DBConstants.GroupMembershipTable.DOMAIN_ID + " = U." + DBConstants.UserTable.DOMAIN_ID + " AND " +
+                "GM." + DBConstants.GroupMembershipTable.DOMAIN_ID + "=:" + DBConstants.GroupMembershipTable.DOMAIN_ID + " AND "+
+                "GM." + DBConstants.GroupMembershipTable.PARENT_ID + "=:" + DBConstants.GroupMembershipTable.PARENT_ID + " AND GM." + DBConstants.GroupMembershipTable.CHILD_TYPE
+                + "=:" + DBConstants.GroupMembershipTable.CHILD_TYPE;
+        Map<String,Object> queryParameters = new HashMap<>();
+        queryParameters.put(DBConstants.GroupMembershipTable.DOMAIN_ID, domainId);
+        queryParameters.put(DBConstants.GroupMembershipTable.PARENT_ID, groupId);
+        queryParameters.put(DBConstants.GroupMembershipTable.CHILD_TYPE, GroupChildType.USER.toString());
+        UserRepository userRepository = new UserRepository();
+        List<User> users = userRepository.select(queryString, queryParameters, 0, -1);
+        return users;
+    }
+
+    public List<UserGroup> getAllChildGroups(String domainId, String groupId) throws SharingRegistryException {
+        String queryString = "SELECT DISTINCT G FROM " + UserGroupEntity.class.getSimpleName() + " G, " + GroupMembershipEntity.class.getSimpleName()
+                + " GM WHERE GM." + DBConstants.GroupMembershipTable.CHILD_ID + " = G." + DBConstants.UserGroupTable.GROUP_ID + " AND " +
+                "GM." + DBConstants.GroupMembershipTable.DOMAIN_ID + " = G." + DBConstants.UserGroupTable.DOMAIN_ID + " AND " +
+                "GM." + DBConstants.GroupMembershipTable.DOMAIN_ID+"=:"+DBConstants.GroupMembershipTable.DOMAIN_ID + " AND "+
+                "GM." + DBConstants.GroupMembershipTable.PARENT_ID+"=:"+DBConstants.GroupMembershipTable.PARENT_ID + " AND GM." + DBConstants.GroupMembershipTable.CHILD_TYPE
+                + "=:" + DBConstants.GroupMembershipTable.CHILD_TYPE;
+        Map<String,Object> queryParameters = new HashMap<>();
+        queryParameters.put(DBConstants.GroupMembershipTable.DOMAIN_ID, domainId);
+        queryParameters.put(DBConstants.GroupMembershipTable.PARENT_ID, groupId);
+        queryParameters.put(DBConstants.GroupMembershipTable.CHILD_TYPE, GroupChildType.GROUP.toString());
+        UserGroupRepository userGroupRepository = new UserGroupRepository();
+        List<UserGroup> groups = userGroupRepository.select(queryString, queryParameters,0, -1);
+        return groups;
+    }
+
+    public List<UserGroup> getAllMemberGroupsForUser(String domainId, String userId) throws SharingRegistryException {
+        String queryString = "SELECT DISTINCT G FROM " + UserGroupEntity.class.getSimpleName() + " G, " + GroupMembershipEntity.class.getSimpleName()
+                + " GM WHERE GM." + DBConstants.GroupMembershipTable.PARENT_ID + " = G." + DBConstants.UserGroupTable.GROUP_ID + " AND " +
+                "GM." + DBConstants.GroupMembershipTable.DOMAIN_ID + " = G." + DBConstants.UserGroupTable.DOMAIN_ID + " AND " +
+                "GM." + DBConstants.GroupMembershipTable.DOMAIN_ID+"=:"+DBConstants.GroupMembershipTable.DOMAIN_ID + " AND "+
+                "GM." + DBConstants.GroupMembershipTable.CHILD_ID+"=:"+DBConstants.GroupMembershipTable.CHILD_ID + " AND GM." + DBConstants.GroupMembershipTable.CHILD_TYPE
+                + "=:" + DBConstants.GroupMembershipTable.CHILD_TYPE + " AND " +
+                "G." + DBConstants.UserGroupTable.GROUP_CARDINALITY + "=:" + DBConstants.UserGroupTable.GROUP_CARDINALITY;
+        Map<String,Object> queryParameters = new HashMap<>();
+        queryParameters.put(DBConstants.GroupMembershipTable.DOMAIN_ID, domainId);
+        queryParameters.put(DBConstants.GroupMembershipTable.CHILD_ID, userId);
+        queryParameters.put(DBConstants.GroupMembershipTable.CHILD_TYPE, GroupChildType.USER.toString());
+        queryParameters.put(DBConstants.UserGroupTable.GROUP_CARDINALITY, GroupCardinality.MULTI_USER.name());
+        UserGroupRepository userGroupRepository = new UserGroupRepository();
+        List<UserGroup> groups = userGroupRepository.select(queryString, queryParameters, 0, -1);
+        return groups;
+    }
+
+    public List<GroupMembership> getAllParentMembershipsForChild(String domainId, String childId) throws SharingRegistryException {
+        List<GroupMembership> finalParentGroups = new ArrayList<>();
+        Map<String, String> filters = new HashMap<>();
+        filters.put(DBConstants.GroupMembershipTable.CHILD_ID, childId);
+        filters.put(DBConstants.GroupMembershipTable.DOMAIN_ID, domainId);
+        LinkedList<GroupMembership> temp = new LinkedList<>();
+        select(filters, 0, -1).stream().forEach(m -> temp.addLast(m));
+        while (temp.size() > 0){
+            GroupMembership gm = temp.pop();
+            filters = new HashMap<>();
+            filters.put(DBConstants.GroupMembershipTable.CHILD_ID, gm.getParentId());
+            filters.put(DBConstants.GroupMembershipTable.DOMAIN_ID, domainId);
+            select(filters, 0, -1).stream().forEach(m -> temp.addLast(m));
+            finalParentGroups.add(gm);
+        }
+        return finalParentGroups;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/PermissionTypeRepository.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/PermissionTypeRepository.java
new file mode 100644
index 0000000..c3c4a67
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/PermissionTypeRepository.java
@@ -0,0 +1,52 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.custos.sharing.registry.db.repositories;
+
+import org.apache.custos.sharing.registry.db.entities.PermissionTypeEntity;
+import org.apache.custos.sharing.registry.db.entities.PermissionTypePK;
+import org.apache.custos.sharing.registry.db.utils.DBConstants;
+import org.apache.custos.sharing.registry.models.PermissionType;
+import org.apache.custos.sharing.registry.models.SharingRegistryException;
+import org.apache.custos.sharing.registry.server.SharingRegistryServerHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.List;
+
+public class PermissionTypeRepository extends AbstractRepository<PermissionType, PermissionTypeEntity, PermissionTypePK> {
+    private final static Logger logger = LoggerFactory.getLogger(PermissionTypeRepository.class);
+
+    public PermissionTypeRepository() {
+        super(PermissionType.class, PermissionTypeEntity.class);
+    }
+
+    public String getOwnerPermissionTypeIdForDomain(String domainId) throws SharingRegistryException {
+        HashMap<String, String> filters = new HashMap<>();
+        filters.put(DBConstants.PermissionTypeTable.DOMAIN_ID, domainId);
+        filters.put(DBConstants.PermissionTypeTable.NAME, SharingRegistryServerHandler.OWNER_PERMISSION_NAME);
+        List<PermissionType> permissionTypeList = select(filters, 0, -1);
+        if(permissionTypeList.size() != 1){
+            throw new SharingRegistryException("GLOBAL Permission inconsistency. Found " + permissionTypeList.size()
+                    + " records with " + SharingRegistryServerHandler.OWNER_PERMISSION_NAME + " name");
+        }
+        return permissionTypeList.get(0).getPermissionTypeId();
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/SharingRepository.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/SharingRepository.java
new file mode 100644
index 0000000..29ee9a9
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/SharingRepository.java
@@ -0,0 +1,115 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.repositories;
+
+import org.apache.custos.sharing.registry.db.entities.SharingEntity;
+import org.apache.custos.sharing.registry.db.entities.SharingPK;
+import org.apache.custos.sharing.registry.db.utils.DBConstants;
+import org.apache.custos.sharing.registry.models.Sharing;
+import org.apache.custos.sharing.registry.models.SharingRegistryException;
+import org.apache.custos.sharing.registry.models.SharingType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.Query;
+
+public class SharingRepository extends AbstractRepository<Sharing, SharingEntity, SharingPK> {
+    private final static Logger logger = LoggerFactory.getLogger(SharingRepository.class);
+
+    public SharingRepository() {
+        super(Sharing.class, SharingEntity.class);
+    }
+
+    public List<Sharing> getIndirectSharedChildren(String domainId, String parentId, String permissionTypeId) throws SharingRegistryException {
+        HashMap<String, String> filters = new HashMap<>();
+        filters.put(DBConstants.SharingTable.DOMAIN_ID, domainId);
+        filters.put(DBConstants.SharingTable.INHERITED_PARENT_ID, parentId);
+        filters.put(DBConstants.SharingTable.SHARING_TYPE, SharingType.INDIRECT_CASCADING.toString());
+        filters.put(DBConstants.SharingTable.PERMISSION_TYPE_ID, permissionTypeId);
+
+        return select(filters, 0, -1);
+    }
+
+    public List<Sharing> getCascadingPermissionsForEntity(String domainId, String entityId) throws SharingRegistryException {
+        String query = "SELECT DISTINCT p from " + SharingEntity.class.getSimpleName() + " as p";
+        query += " WHERE ";
+        query += "p." + DBConstants.SharingTable.DOMAIN_ID + " = :" + DBConstants.SharingTable.DOMAIN_ID + " AND ";
+        query += "p." + DBConstants.SharingTable.ENTITY_ID + " = :" + DBConstants.SharingTable.ENTITY_ID + " AND ";
+        query += "p." + DBConstants.SharingTable.SHARING_TYPE + " IN('" + SharingType.DIRECT_CASCADING.toString()
+                + "', '" + SharingType.INDIRECT_CASCADING + "') ";
+        query += " ORDER BY p.createdTime DESC";
+        Map<String,Object> queryParameters = new HashMap<>();
+        queryParameters.put(DBConstants.SharingTable.DOMAIN_ID, domainId);
+        queryParameters.put(DBConstants.SharingTable.ENTITY_ID, entityId);
+        return select(query, queryParameters, 0, -1);
+    }
+
+    public boolean hasAccess(String domainId, String entityId, List<String> groupIds, List<String> permissionTypeIds) throws SharingRegistryException {
+        Map<String,Object> queryParameters = new HashMap<>();
+        String query = "SELECT p from " + SharingEntity.class.getSimpleName() + " as p";
+        query += " WHERE ";
+        query += "p." + DBConstants.SharingTable.DOMAIN_ID + " = :" + DBConstants.SharingTable.DOMAIN_ID + " AND ";
+        query += "p." + DBConstants.SharingTable.ENTITY_ID + " = :" + DBConstants.SharingTable.ENTITY_ID + " AND ";
+        queryParameters.put(DBConstants.SharingTable.DOMAIN_ID, domainId);
+        queryParameters.put(DBConstants.SharingTable.ENTITY_ID, entityId);
+        query += "p." + DBConstants.SharingTable.PERMISSION_TYPE_ID + " IN :" + DBConstants.SharingTable.PERMISSION_TYPE_ID + " AND ";
+        queryParameters.put(DBConstants.SharingTable.PERMISSION_TYPE_ID, permissionTypeIds);
+        query += "p." + DBConstants.SharingTable.GROUP_ID + " IN :" + DBConstants.SharingTable.GROUP_ID + " ";
+        queryParameters.put(DBConstants.SharingTable.GROUP_ID, groupIds);
+        query += " ORDER BY p.createdTime DESC";
+        return select(query, queryParameters, 0, -1).size() > 0;
+    }
+
+    public int getSharedCount(String domainId, String entityId) throws SharingRegistryException {
+        Map<String,Object> queryParameters = new HashMap<>();
+        String query = "SELECT p from " + SharingEntity.class.getSimpleName() + " as p";
+        query += " WHERE ";
+        query += "p." + DBConstants.SharingTable.DOMAIN_ID + " = :" + DBConstants.SharingTable.DOMAIN_ID + " AND ";
+        queryParameters.put(DBConstants.SharingTable.DOMAIN_ID, domainId);
+        query += "p." + DBConstants.SharingTable.ENTITY_ID + " = :" + DBConstants.SharingTable.ENTITY_ID + " AND ";
+        queryParameters.put(DBConstants.SharingTable.ENTITY_ID, entityId);
+        String permissionTypeIdString = (new PermissionTypeRepository()).getOwnerPermissionTypeIdForDomain(domainId);
+        query += "p." + DBConstants.SharingTable.PERMISSION_TYPE_ID + " <> :" + DBConstants.SharingTable.PERMISSION_TYPE_ID + " AND ";
+        queryParameters.put(DBConstants.SharingTable.PERMISSION_TYPE_ID, permissionTypeIdString);
+        query += "p." + DBConstants.SharingTable.SHARING_TYPE + " <> :" + DBConstants.SharingTable.SHARING_TYPE;
+        queryParameters.put(DBConstants.SharingTable.SHARING_TYPE, SharingType.INDIRECT_CASCADING.toString());
+        return select(query, queryParameters, 0, -1).size();
+    }
+
+    public void removeAllIndirectCascadingPermissionsForEntity(String domainId, String entityId) throws SharingRegistryException {
+        String query = "DELETE from " + SharingEntity.class.getSimpleName() + " as p";
+        query += " WHERE ";
+        query += "p." + DBConstants.SharingTable.DOMAIN_ID + " = :" + DBConstants.SharingTable.DOMAIN_ID + " AND ";
+        query += "p." + DBConstants.SharingTable.ENTITY_ID + " = :" + DBConstants.SharingTable.ENTITY_ID + " AND ";
+        query += "p." + DBConstants.SharingTable.SHARING_TYPE + " = '" + SharingType.INDIRECT_CASCADING.toString() + "' ";
+        final String finalQuery = query;
+        execute(em -> {
+            Query q = em.createQuery(finalQuery);
+            q.setParameter(DBConstants.SharingTable.DOMAIN_ID, domainId);
+            q.setParameter(DBConstants.SharingTable.ENTITY_ID, entityId);
+            q.executeUpdate();
+            return true;
+        });
+    }
+}
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/UserGroupRepository.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/UserGroupRepository.java
new file mode 100644
index 0000000..9cac79c
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/UserGroupRepository.java
@@ -0,0 +1,95 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.repositories;
+
+import org.apache.custos.sharing.registry.db.entities.SharingEntity;
+import org.apache.custos.sharing.registry.db.entities.UserGroupEntity;
+import org.apache.custos.sharing.registry.db.entities.UserGroupPK;
+import org.apache.custos.sharing.registry.db.utils.DBConstants;
+import org.apache.custos.sharing.registry.models.GroupCardinality;
+import org.apache.custos.sharing.registry.models.SharingRegistryException;
+import org.apache.custos.sharing.registry.models.SharingType;
+import org.apache.custos.sharing.registry.models.UserGroup;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class UserGroupRepository extends AbstractRepository<UserGroup, UserGroupEntity, UserGroupPK> {
+    private final static Logger logger = LoggerFactory.getLogger(UserGroupRepository.class);
+
+    public UserGroupRepository() {
+        super(UserGroup.class, UserGroupEntity.class);
+    }
+
+    public List<UserGroup> getAccessibleGroups(String domainId, String entityId, String permissionTypeId) throws SharingRegistryException {
+        return getAccessibleGroupsInternal(domainId, entityId, permissionTypeId);
+    }
+
+    public List<UserGroup> getDirectlyAccessibleGroups(String domainId, String entityId, String permissionTypeId) throws SharingRegistryException {
+        return getAccessibleGroupsInternal(domainId, entityId, permissionTypeId, SharingType.DIRECT_CASCADING, SharingType.DIRECT_NON_CASCADING);
+    }
+
+    private List<UserGroup> getAccessibleGroupsInternal(String domainId, String entityId, String permissionTypeId, SharingType... sharingTypes) throws SharingRegistryException {
+        String query = "SELECT DISTINCT g from " + UserGroupEntity.class.getSimpleName() + " g, " + SharingEntity.class.getSimpleName() + " s";
+        query += " WHERE ";
+        query += "g." + DBConstants.UserGroupTable.GROUP_ID + " = s." + DBConstants.SharingTable.GROUP_ID + " AND ";
+        query += "g." + DBConstants.UserGroupTable.DOMAIN_ID + " = s." + DBConstants.SharingTable.DOMAIN_ID + " AND ";
+        query += "g." + DBConstants.UserGroupTable.DOMAIN_ID + " = :" + DBConstants.UserGroupTable.DOMAIN_ID + " AND ";
+        query += "s." + DBConstants.SharingTable.ENTITY_ID + " = :" + DBConstants.SharingTable.ENTITY_ID + " AND ";
+        query += "s." + DBConstants.SharingTable.PERMISSION_TYPE_ID + " = :" + DBConstants.SharingTable.PERMISSION_TYPE_ID + " AND ";
+        query += "g." + DBConstants.UserGroupTable.GROUP_CARDINALITY + " = :" + DBConstants.UserGroupTable.GROUP_CARDINALITY;
+        if (!Arrays.asList(sharingTypes).isEmpty()) {
+            query += " AND s." + DBConstants.SharingTable.SHARING_TYPE + " IN :" + DBConstants.SharingTable.SHARING_TYPE;
+        }
+        query += " ORDER BY s.createdTime DESC";
+        Map<String,Object> queryParameters = new HashMap<>();
+        queryParameters.put(DBConstants.UserGroupTable.DOMAIN_ID, domainId);
+        queryParameters.put(DBConstants.SharingTable.ENTITY_ID, entityId);
+        queryParameters.put(DBConstants.SharingTable.PERMISSION_TYPE_ID, permissionTypeId);
+        queryParameters.put(DBConstants.UserGroupTable.GROUP_CARDINALITY, GroupCardinality.MULTI_USER.toString());
+        if (!Arrays.asList(sharingTypes).isEmpty()) {
+            queryParameters.put(DBConstants.SharingTable.SHARING_TYPE, Arrays.asList(sharingTypes).stream().map(s -> s.name()).collect(Collectors.toList()));
+        }
+        return select(query, queryParameters, 0, -1);
+    }
+
+    //checks whether is shared with any user or group with any permission
+    public boolean isShared(String domainId, String entityId) throws SharingRegistryException {
+        String query = "SELECT DISTINCT g from " + UserGroupEntity.class.getSimpleName() + " g, " + SharingEntity.class.getSimpleName() + " s";
+        query += " WHERE ";
+        query += "g." + DBConstants.UserGroupTable.GROUP_ID + " = s." + DBConstants.SharingTable.GROUP_ID + " AND ";
+        query += "g." + DBConstants.UserGroupTable.DOMAIN_ID + " = s." + DBConstants.SharingTable.DOMAIN_ID + " AND ";
+        query += "g." + DBConstants.UserGroupTable.DOMAIN_ID + " = :" + DBConstants.UserGroupTable.DOMAIN_ID + " AND ";
+        query += "s." + DBConstants.SharingTable.ENTITY_ID + " = :" + DBConstants.SharingTable.ENTITY_ID + " AND ";
+        query += "s." + DBConstants.SharingTable.PERMISSION_TYPE_ID + " <> :" + DBConstants.SharingTable.PERMISSION_TYPE_ID;
+        query += " ORDER BY s.createdTime DESC";
+        Map<String,Object> queryParameters = new HashMap<>();
+        queryParameters.put(DBConstants.UserGroupTable.DOMAIN_ID, domainId);
+        queryParameters.put(DBConstants.SharingTable.ENTITY_ID, entityId);
+        String ownerPermissionTypeIdForDomain = (new PermissionTypeRepository()).getOwnerPermissionTypeIdForDomain(domainId);
+        queryParameters.put(DBConstants.SharingTable.PERMISSION_TYPE_ID, ownerPermissionTypeIdForDomain);
+        return select(query, queryParameters, 0, -1).size() != 0;
+    }
+}
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/UserRepository.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/UserRepository.java
new file mode 100644
index 0000000..4d28229
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/repositories/UserRepository.java
@@ -0,0 +1,79 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.custos.sharing.registry.db.repositories;
+
+import org.apache.custos.sharing.registry.db.entities.SharingEntity;
+import org.apache.custos.sharing.registry.db.entities.UserEntity;
+import org.apache.custos.sharing.registry.db.entities.UserPK;
+import org.apache.custos.sharing.registry.db.utils.DBConstants;
+import org.apache.custos.sharing.registry.models.SharingRegistryException;
+import org.apache.custos.sharing.registry.models.SharingType;
+import org.apache.custos.sharing.registry.models.User;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class UserRepository extends AbstractRepository<User, UserEntity, UserPK> {
+    private final static Logger logger = LoggerFactory.getLogger(UserRepository.class);
+
+    public UserRepository() {
+        super(User.class, UserEntity.class);
+    }
+
+
+    public List<User> getAccessibleUsers(String domainId, String entityId, String permissionTypeId) throws SharingRegistryException {
+        if(permissionTypeId.equals((new PermissionTypeRepository()).getOwnerPermissionTypeIdForDomain(domainId))){
+            return getAccessibleUsersInternal(domainId, entityId, permissionTypeId, SharingType.DIRECT_CASCADING, SharingType.DIRECT_NON_CASCADING);
+        } else {
+            return getAccessibleUsersInternal(domainId, entityId, permissionTypeId);
+        }
+    }
+
+    public List<User> getDirectlyAccessibleUsers(String domainId, String entityId, String permissionTypeId) throws SharingRegistryException {
+        return getAccessibleUsersInternal(domainId, entityId, permissionTypeId, SharingType.DIRECT_CASCADING, SharingType.DIRECT_NON_CASCADING);
+    }
+
+    private List<User> getAccessibleUsersInternal(String domainId, String entityId, String permissionTypeId, SharingType... sharingTypes) throws SharingRegistryException {
+        Map<String,Object> queryParameters = new HashMap<>();
+        String query = "SELECT DISTINCT u from " + UserEntity.class.getSimpleName() + " u, " + SharingEntity.class.getSimpleName() + " s";
+        query += " WHERE ";
+        query += "u." + DBConstants.UserTable.USER_ID + " = s." + DBConstants.SharingTable.GROUP_ID + " AND ";
+        query += "u." + DBConstants.UserTable.DOMAIN_ID + " = s." + DBConstants.SharingTable.DOMAIN_ID + " AND ";
+        query += "u." + DBConstants.UserTable.DOMAIN_ID + " = :" + DBConstants.UserTable.DOMAIN_ID + " AND ";
+        query += "s." + DBConstants.SharingTable.ENTITY_ID + " = :" + DBConstants.SharingTable.ENTITY_ID + " AND ";
+        query += "s." + DBConstants.SharingTable.PERMISSION_TYPE_ID + " = :" + DBConstants.SharingTable.PERMISSION_TYPE_ID;
+        queryParameters.put(DBConstants.UserTable.DOMAIN_ID, domainId);
+        queryParameters.put(DBConstants.SharingTable.ENTITY_ID, entityId);
+        queryParameters.put(DBConstants.SharingTable.PERMISSION_TYPE_ID, permissionTypeId);
+
+        if (!Arrays.asList(sharingTypes).isEmpty()) {
+            query += " AND s." + DBConstants.SharingTable.SHARING_TYPE + " IN :" + DBConstants.SharingTable.SHARING_TYPE;
+            queryParameters.put(DBConstants.SharingTable.SHARING_TYPE, Arrays.asList(sharingTypes).stream().map(s -> s.name()).collect(Collectors.toList()));
+        }
+
+        query += " ORDER BY s.createdTime DESC";
+        return select(query, queryParameters,0, -1);
+    }
+}
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/Committer.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/Committer.java
new file mode 100644
index 0000000..28d2e09
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/Committer.java
@@ -0,0 +1,26 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.utils;
+
+@FunctionalInterface
+public interface Committer<T, R>  {
+
+    R commit(T t);
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/DBConstants.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/DBConstants.java
new file mode 100644
index 0000000..5f8f549
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/DBConstants.java
@@ -0,0 +1,106 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.utils;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DBConstants {
+    private final static Logger logger = LoggerFactory.getLogger(DBConstants.class);
+
+    public static int SELECT_MAX_ROWS = 1000;
+
+    public static class DomainTable {
+        public static final String DOMAIN_ID = "domainId";
+        public static final String NAME = "name";
+        public static final String DESCRIPTION = "description";
+        public static final String CREATED_TIME = "createdTime";
+        public static final String UPDATED_TIME = "updatedTime";
+    }
+
+    public static class UserTable {
+        public static final String USER_ID = "userId";
+        public static final String DOMAIN_ID = "domainId";
+        public static final String USER_NAME = "userName";
+        public static final String CREATED_TIME = "createdTime";
+        public static final String UPDATED_TIME = "updatedTime";
+    }
+
+    public static class UserGroupTable {
+        public static final String GROUP_ID = "groupId";
+        public static final String DOMAIN_ID = "domainId";
+        public static final String NAME = "name";
+        public static final String DESCRIPTION = "description";
+        public static final String OWNER_ID = "ownerId";
+        public static final String GROUP_TYPE = "groupType";
+        public static final String GROUP_CARDINALITY = "groupCardinality";
+        public static final String CREATED_TIME = "createdTime";
+        public static final String UPDATED_TIME = "updatedTime";
+    }
+
+    public static class GroupMembershipTable {
+        public static final String PARENT_ID = "parentId";
+        public static final String CHILD_ID = "childId";
+        public static final String CHILD_TYPE = "childType";
+        public static final String DOMAIN_ID = "domainId";
+        public static final String CREATED_TIME = "createdTime";
+        public static final String UPDATED_TIME = "updatedTime";
+    }
+
+    public static class EntityTypeTable {
+        public static final String ENTITY_TYPE_ID = "entityTypeId";
+        public static final String DOMAIN_ID = "domainId";
+        public static final String CREATED_TIME = "createdTime";
+        public static final String UPDATED_TIME = "updatedTime";
+    }
+
+    public static class PermissionTypeTable {
+        public static final String ENTITY_TYPE_ID = "permissionTypeId";
+        public static final String DOMAIN_ID = "domainId";
+        public static final String NAME = "name";
+        public static final String CREATED_TIME = "createdTime";
+        public static final String UPDATED_TIME = "updatedTime";
+    }
+
+    public static class EntityTable {
+        public static final String ENTITY_ID = "entityId";
+        public static final String PARENT_ENTITY_ID = "parentEntityId";
+        public static final String ENTITY_TYPE_ID = "entityTypeId";
+        public static final String NAME = "name";
+        public static final String DESCRIPTION = "description";
+        public static final String FULL_TEXT = "fullText";
+        public static final String CREATED_TIME = "createdTime";
+        public static final String UPDATED_TIME = "updatedTime";
+        public static final String DOMAIN_ID = "domainId";
+        public static final String ORIGINAL_ENTITY_CREATION_TIME = "originalEntityCreationTime";
+        public static final String SHARED = "shared";
+    }
+
+    public static class SharingTable {
+        public static final String DOMAIN_ID = "domainId";
+        public static final String PERMISSION_TYPE_ID = "permissionTypeId";
+        public static final String ENTITY_ID = "entityId";
+        public static final String GROUP_ID = "groupId";
+        public static final String INHERITED_PARENT_ID = "inheritedParentId";
+        public static final String SHARING_TYPE = "sharingType";
+        public static final String CREATED_TIME = "createdTime";
+        public static final String UPDATED_TIME = "updatedTime";
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/JPAUtils.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/JPAUtils.java
new file mode 100644
index 0000000..f562c15
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/JPAUtils.java
@@ -0,0 +1,35 @@
+/**
+ *
+ * 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.custos.sharing.registry.db.utils;
+
+import org.apache.custos.commons.utils.JDBCConfig;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+
+public class JPAUtils {
+    public static final String PERSISTENCE_UNIT_NAME = "airavata-sharing-registry";
+    private static final JDBCConfig JDBC_CONFIG = new SharingRegistryJDBCConfig();
+    private static final EntityManagerFactory factory = org.apache.custos.commons.utils.JPAUtils.getEntityManagerFactory(PERSISTENCE_UNIT_NAME, JDBC_CONFIG);
+
+    public static EntityManager getEntityManager() {
+        return factory.createEntityManager();
+    }
+}
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/ObjectMapperSingleton.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/ObjectMapperSingleton.java
new file mode 100644
index 0000000..935e949
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/ObjectMapperSingleton.java
@@ -0,0 +1,38 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.custos.sharing.registry.db.utils;
+
+import org.dozer.DozerBeanMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ObjectMapperSingleton extends DozerBeanMapper{
+    private final static Logger logger = LoggerFactory.getLogger(ObjectMapperSingleton.class);
+
+    private static ObjectMapperSingleton instance;
+
+    private ObjectMapperSingleton(){}
+
+    public static ObjectMapperSingleton getInstance(){
+        if(instance == null)
+            instance = new ObjectMapperSingleton();
+        return instance;
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/SharingRegistryDBInitConfig.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/SharingRegistryDBInitConfig.java
new file mode 100644
index 0000000..f95246a
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/SharingRegistryDBInitConfig.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.custos.sharing.registry.db.utils;
+
+
+import org.apache.custos.commons.utils.DBInitConfig;
+import org.apache.custos.commons.utils.JDBCConfig;
+
+public class SharingRegistryDBInitConfig implements DBInitConfig {
+    private String dbInitScriptPrefix = "database_scripts/sharing-registry";
+
+    @Override
+    public JDBCConfig getJDBCConfig() {
+        return new SharingRegistryJDBCConfig();
+    }
+
+    @Override
+    public String getDBInitScriptPrefix() {
+        return this.dbInitScriptPrefix;
+    }
+
+    @Override
+    public String getCheckTableName() {
+        return "CONFIGURATION";
+    }
+
+    public void setDBInitScriptPrefix(String dbInitScriptPrefix) {
+        this.dbInitScriptPrefix = dbInitScriptPrefix;
+    }
+}
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/SharingRegistryJDBCConfig.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/SharingRegistryJDBCConfig.java
new file mode 100644
index 0000000..747d93f
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/db/utils/SharingRegistryJDBCConfig.java
@@ -0,0 +1,67 @@
+/*
+ * 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.custos.sharing.registry.db.utils;
+
+import org.apache.custos.commons.exceptions.ApplicationSettingsException;
+import org.apache.custos.commons.utils.JDBCConfig;
+import org.apache.custos.commons.utils.ServerSettings;
+
+public class SharingRegistryJDBCConfig implements JDBCConfig {
+
+    private static final String SHARING_REG_JDBC_DRIVER = "sharingcatalog.jdbc.driver";
+    private static final String SHARING_REG_JDBC_URL = "sharingcatalog.jdbc.url";
+    private static final String SHARING_REG_JDBC_USER = "sharingcatalog.jdbc.user";
+    private static final String SHARING_REG_JDBC_PWD = "sharingcatalog.jdbc.password";
+    private static final String SHARING_REG_VALIDATION_QUERY = "sharingcatalog.validationQuery";
+
+    @Override
+    public String getURL() {
+        return readServerProperties(SHARING_REG_JDBC_URL);
+    }
+
+    @Override
+    public String getDriver() {
+        return readServerProperties(SHARING_REG_JDBC_DRIVER);
+    }
+
+    @Override
+    public String getUser() {
+        return readServerProperties(SHARING_REG_JDBC_USER);
+    }
+
+    @Override
+    public String getPassword() {
+        return readServerProperties(SHARING_REG_JDBC_PWD);
+    }
+
+    @Override
+    public String getValidationQuery() {
+        return readServerProperties(SHARING_REG_VALIDATION_QUERY);
+    }
+
+    private String readServerProperties(String propertyName) {
+        try {
+            return ServerSettings.getSetting(propertyName);
+        } catch (ApplicationSettingsException e) {
+            throw new RuntimeException("Unable to read server.properties...", e);
+        }
+    }
+}
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/server/ServerMain.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/server/ServerMain.java
new file mode 100644
index 0000000..0128361
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/server/ServerMain.java
@@ -0,0 +1,101 @@
+/**
+ *
+ * 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.custos.sharing.registry.server;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+public class ServerMain {
+    private final static Logger logger = LoggerFactory.getLogger(ServerMain.class);
+
+    private static int serverPID = -1;
+    private static final String stopFileNamePrefix = "server_stop";
+    private static final String serverStartedFileNamePrefix = "server_start";
+
+    public static void main(String[] args) {
+        try {
+            setServerStarted();
+            new SharingRegistryServer().start();
+        } catch (Exception e) {
+            logger.error(e.getMessage(), e);
+        }
+    }
+
+    @SuppressWarnings({"resource"})
+    private static void setServerStarted() {
+        try {
+            serverPID = getPID();
+            deleteOldStopRequests();
+            File serverStartedFile = null;
+            serverStartedFile = new File(getServerStartedFileName());
+            serverStartedFile.createNewFile();
+            serverStartedFile.deleteOnExit();
+            new RandomAccessFile(serverStartedFile, "rw").getChannel().lock();
+        } catch (FileNotFoundException e) {
+            logger.warn(e.getMessage(), e);
+        } catch (IOException e) {
+            logger.warn(e.getMessage(), e);
+        }
+    }
+
+    private static String getServerStartedFileName() {
+        String SHARING_REGISTRY_HOME = System.getenv("" +"SHARING_REGISTRY_HOME");
+        if(SHARING_REGISTRY_HOME==null)
+            SHARING_REGISTRY_HOME = "/tmp";
+        else
+            SHARING_REGISTRY_HOME = SHARING_REGISTRY_HOME + "/bin";
+        return new File(SHARING_REGISTRY_HOME, serverStartedFileNamePrefix + "_" + Integer.toString(serverPID)).toString();
+    }
+
+    private static int getPID() {
+        try {
+            java.lang.management.RuntimeMXBean runtime = java.lang.management.ManagementFactory
+                    .getRuntimeMXBean();
+            java.lang.reflect.Field jvm = runtime.getClass()
+                    .getDeclaredField("jvm");
+            jvm.setAccessible(true);
+            sun.management.VMManagement mgmt = (sun.management.VMManagement) jvm
+                    .get(runtime);
+            java.lang.reflect.Method pid_method = mgmt.getClass()
+                    .getDeclaredMethod("getProcessId");
+            pid_method.setAccessible(true);
+
+            int pid = (Integer) pid_method.invoke(mgmt);
+            return pid;
+        } catch (Exception e) {
+            return -1;
+        }
+    }
+
+    private static void deleteOldStopRequests() {
+        File[] files = new File(".").listFiles();
+        for (File file : files) {
+            if (file.getName().contains(stopFileNamePrefix)) {
+                file.delete();
+            }
+
+        }
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/server/SharingRegistryServer.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/server/SharingRegistryServer.java
new file mode 100644
index 0000000..78fbb51
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/server/SharingRegistryServer.java
@@ -0,0 +1,191 @@
+/**
+ *
+ * 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.custos.sharing.registry.server;
+
+import org.apache.custos.commons.exceptions.CustosException;
+import org.apache.custos.commons.utils.IServer;
+import org.apache.custos.commons.utils.ServerSettings;
+import org.apache.custos.sharing.registry.db.utils.SharingRegistryDBInitConfig;
+import org.apache.custos.sharing.registry.models.SharingRegistryException;
+import org.apache.custos.sharing.registry.service.cpi.SharingRegistryService;
+import org.apache.thrift.server.TServer;
+import org.apache.thrift.server.TThreadPoolServer;
+import org.apache.thrift.transport.TSSLTransportFactory;
+import org.apache.thrift.transport.TServerSocket;
+import org.apache.thrift.transport.TServerTransport;
+import org.apache.thrift.transport.TTransportException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+
+public class SharingRegistryServer implements IServer {
+    private final static Logger logger = LoggerFactory.getLogger(SharingRegistryServer.class);
+
+    public static final String SHARING_REG_SERVER_HOST = "sharing.registry.server.host";
+    public static final String SHARING_REG_SERVER_PORT = "sharing.registry.server.port";
+
+    private static final String SERVER_NAME = "Sharing Registry Server";
+    private static final String SERVER_VERSION = "1.0";
+
+    private IServer.ServerStatus status;
+    private TServer server;
+    private boolean testMode = false;
+
+    public SharingRegistryServer() {
+        setStatus(IServer.ServerStatus.STOPPED);
+    }
+
+    @Override
+    public String getName() {
+        return SERVER_NAME;
+    }
+
+    @Override
+    public String getVersion() {
+        return SERVER_VERSION;
+    }
+
+    @Override
+    public void start() throws Exception {
+        try {
+            setStatus(IServer.ServerStatus.STARTING);
+
+            final int serverPort = Integer.parseInt(ServerSettings.getSetting(SHARING_REG_SERVER_PORT));
+            final String serverHost = ServerSettings.getSetting(SHARING_REG_SERVER_HOST);
+            SharingRegistryService.Processor processor = new SharingRegistryService.Processor(
+                    new SharingRegistryServerHandler(createSharingRegistryDBInitConfig()));
+
+            TServerTransport serverTransport;
+
+            if (!ServerSettings.isSharingTLSEnabled()) {
+                InetSocketAddress inetSocketAddress = new InetSocketAddress(serverHost, serverPort);
+                serverTransport = new TServerSocket(inetSocketAddress);
+                TThreadPoolServer.Args options = new TThreadPoolServer.Args(serverTransport);
+                options.minWorkerThreads = 30;
+                server = new TThreadPoolServer(options.processor(processor));
+            }else{
+                TSSLTransportFactory.TSSLTransportParameters TLSParams =
+                        new TSSLTransportFactory.TSSLTransportParameters();
+                TLSParams.requireClientAuth(true);
+                TLSParams.setKeyStore(ServerSettings.getKeyStorePath(), ServerSettings.getKeyStorePassword());
+                TLSParams.setTrustStore(ServerSettings.getTrustStorePath(), ServerSettings.getTrustStorePassword());
+                TServerSocket TLSServerTransport = TSSLTransportFactory.getServerSocket(
+                        serverPort, ServerSettings.getTLSClientTimeout(),
+                        InetAddress.getByName(serverHost), TLSParams);
+                TThreadPoolServer.Args options = new TThreadPoolServer.Args(TLSServerTransport);
+                options.minWorkerThreads = 30;
+                server = new TThreadPoolServer(options.processor(processor));
+            }
+
+            new Thread() {
+                public void run() {
+                    server.serve();
+                    setStatus(IServer.ServerStatus.STOPPED);
+                    logger.info("Sharing Registry Server Stopped.");
+                }
+            }.start();
+            new Thread() {
+                public void run() {
+                    while (!server.isServing()) {
+                        try {
+                            Thread.sleep(500);
+                        } catch (InterruptedException e) {
+                            break;
+                        }
+                    }
+                    if (server.isServing()) {
+//                        try {
+//                            logger.info("Register sharing service with DB Event publishers");
+//                            //SharingServiceDBEventMessagingFactory.registerSharingServiceWithPublishers(Constants.PUBLISHERS);
+//
+//                            logger.info("Start sharing service DB Event subscriber");
+//                            //SharingServiceDBEventMessagingFactory.getDBEventSubscriber();
+//                        } catch (CustosException | SharingRegistryException e) {
+//                            logger.error("Error starting sharing service. Error setting up DB event services.");
+//                            server.stop();
+//                        }
+                        setStatus(IServer.ServerStatus.STARTED);
+                        logger.info("Starting Sharing Registry Server on Port " + serverPort);
+                        logger.info("Listening to Sharing Registry server clients ....");
+                    }
+                }
+            }.start();
+
+        } catch (TTransportException e) {
+            setStatus(IServer.ServerStatus.FAILED);
+            throw new Exception("Error while starting the Sharing Registry service", e);
+        }
+    }
+
+    @Override
+    public void stop() throws Exception {
+        if (server!=null && server.isServing()){
+            setStatus(IServer.ServerStatus.STOPING);
+            server.stop();
+        }
+    }
+
+    @Override
+    public void restart() throws Exception {
+        stop();
+        start();
+    }
+
+    @Override
+    public void configure() throws Exception {
+
+    }
+
+    @Override
+    public IServer.ServerStatus getStatus() throws Exception {
+        return status;
+    }
+
+    private void setStatus(IServer.ServerStatus stat){
+        status=stat;
+        status.updateTime();
+    }
+
+    public TServer getServer() {
+        return server;
+    }
+
+    public void setServer(TServer server) {
+        this.server = server;
+    }
+
+    public boolean isTestMode() {
+        return testMode;
+    }
+
+    public void setTestMode(boolean testMode) {
+        this.testMode = testMode;
+    }
+
+    private SharingRegistryDBInitConfig createSharingRegistryDBInitConfig() {
+        SharingRegistryDBInitConfig sharingRegistryDBInitConfig = new SharingRegistryDBInitConfig();
+        if (this.testMode) {
+            sharingRegistryDBInitConfig.setDBInitScriptPrefix("sharing-registry");
+        }
+        return sharingRegistryDBInitConfig;
+    }
+}
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/server/SharingRegistryServerHandler.java b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/server/SharingRegistryServerHandler.java
new file mode 100644
index 0000000..fa9fa3b
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/java/org/apache/custos/sharing/registry/server/SharingRegistryServerHandler.java
@@ -0,0 +1,1273 @@
+/**
+ *
+ * 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.custos.sharing.registry.server;
+
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.custos.commons.exceptions.ApplicationSettingsException;
+import org.apache.custos.commons.utils.DBInitializer;
+import org.apache.custos.sharing.registry.db.entities.*;
+import org.apache.custos.sharing.registry.db.repositories.*;
+import org.apache.custos.sharing.registry.db.utils.DBConstants;
+import org.apache.custos.sharing.registry.db.utils.SharingRegistryDBInitConfig;
+import org.apache.custos.sharing.registry.models.*;
+import org.apache.custos.sharing.registry.service.cpi.SharingRegistryService;
+import org.apache.custos.sharing.registry.service.cpi.sharing_cpiConstants;
+import org.apache.thrift.TException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.*;
+
+public class SharingRegistryServerHandler implements SharingRegistryService.Iface{
+    private final static Logger logger = LoggerFactory.getLogger(SharingRegistryServerHandler.class);
+
+    public static String OWNER_PERMISSION_NAME = "OWNER";
+
+    public SharingRegistryServerHandler(SharingRegistryDBInitConfig sharingRegistryDBInitConfig)  throws ApplicationSettingsException, TException {
+        DBInitializer.initializeDB(sharingRegistryDBInitConfig);
+    }
+
+    @Override
+    public String getAPIVersion() throws TException {
+        return sharing_cpiConstants.SHARING_CPI_VERSION;
+    }
+
+    /**
+     * * Domain Operations
+     * *
+     */
+    @Override
+    public String createDomain(Domain domain) throws SharingRegistryException, DuplicateEntryException, TException {
+        try{
+            domain.setDomainId(domain.getName());
+            if((new DomainRepository()).get(domain.getDomainId()) != null)
+                throw new DuplicateEntryException("There exist domain with given domain id");
+
+            domain.setCreatedTime(System.currentTimeMillis());
+            domain.setUpdatedTime(System.currentTimeMillis());
+            (new DomainRepository()).create(domain);
+
+            //create the global permission for the domain
+            PermissionType permissionType = new PermissionType();
+            permissionType.setPermissionTypeId(domain.getDomainId() + ":" + OWNER_PERMISSION_NAME);
+            permissionType.setDomainId(domain.getDomainId());
+            permissionType.setName(OWNER_PERMISSION_NAME);
+            permissionType.setDescription("GLOBAL permission to " + domain.getDomainId());
+            permissionType.setCreatedTime(System.currentTimeMillis());
+            permissionType.setUpdatedTime(System.currentTimeMillis());
+            (new PermissionTypeRepository()).create(permissionType);
+
+            return domain.getDomainId();
+        }catch (Throwable ex){
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean updateDomain(Domain domain) throws SharingRegistryException, TException {
+        try{
+            Domain oldDomain = (new DomainRepository()).get(domain.getDomainId());
+            domain.setCreatedTime(oldDomain.getCreatedTime());
+            domain.setUpdatedTime(System.currentTimeMillis());
+            domain = getUpdatedObject(oldDomain, domain);
+            (new DomainRepository()).update(domain);
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    /**
+     * <p>API method to check Domain Exists</p>
+     *
+     * @param domainId
+     */
+    @Override
+    public boolean isDomainExists(String domainId) throws SharingRegistryException, TException {
+        try{
+            return (new DomainRepository()).isExists(domainId);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean deleteDomain(String domainId) throws SharingRegistryException, TException {
+        try{
+            (new DomainRepository()).delete(domainId);
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public Domain getDomain(String domainId) throws SharingRegistryException, TException {
+        try{
+            return (new DomainRepository()).get(domainId);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public List<Domain> getDomains(int offset, int limit) throws TException {
+        try{
+            return (new DomainRepository()).select(new HashMap<>(), offset, limit);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    /**
+     * * User Operations
+     * *
+     */
+    @Override
+    public String createUser(User user) throws SharingRegistryException, DuplicateEntryException, TException {
+        try{
+            UserPK userPK = new UserPK();
+            userPK.setUserId(user.getUserId());
+            userPK.setDomainId(user.getDomainId());
+            if((new UserRepository()).get(userPK) != null)
+                throw new DuplicateEntryException("There exist user with given user id");
+
+            user.setCreatedTime(System.currentTimeMillis());
+            user.setUpdatedTime(System.currentTimeMillis());
+            (new UserRepository()).create(user);
+
+            UserGroup userGroup = new UserGroup();
+            userGroup.setGroupId(user.getUserId());
+            userGroup.setDomainId(user.getDomainId());
+            userGroup.setName(user.getUserName());
+            userGroup.setDescription("user " + user.getUserName() + " group");
+            userGroup.setOwnerId(user.getUserId());
+            userGroup.setGroupType(GroupType.USER_LEVEL_GROUP);
+            userGroup.setGroupCardinality(GroupCardinality.SINGLE_USER);
+            (new UserGroupRepository()).create(userGroup);
+
+            return user.getUserId();
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean updatedUser(User user) throws SharingRegistryException, TException {
+        try{
+            UserPK userPK = new UserPK();
+            userPK.setUserId(user.getUserId());
+            userPK.setDomainId(user.getDomainId());
+            User oldUser = (new UserRepository()).get(userPK);
+            user.setCreatedTime(oldUser.getCreatedTime());
+            user.setUpdatedTime(System.currentTimeMillis());
+            user = getUpdatedObject(oldUser, user);
+            (new UserRepository()).update(user);
+
+            UserGroupPK userGroupPK = new UserGroupPK();
+            userGroupPK.setGroupId(user.getUserId());
+            userGroupPK.setDomainId(user.getDomainId());
+            UserGroup userGroup = (new UserGroupRepository()).get(userGroupPK);
+            userGroup.setName(user.getUserName());
+            userGroup.setDescription("user " + user.getUserName() + " group");
+            updateGroup(userGroup);
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    /**
+     * <p>API method to check User Exists</p>
+     *
+     * @param userId
+     */
+    @Override
+    public boolean isUserExists(String domainId, String userId) throws SharingRegistryException, TException {
+        try{
+            UserPK userPK = new UserPK();
+            userPK.setDomainId(domainId);
+            userPK.setUserId(userId);
+            return (new UserRepository()).isExists(userPK);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean deleteUser(String domainId, String userId) throws SharingRegistryException, TException {
+        try{
+            UserPK userPK = new UserPK();
+            userPK.setUserId(userId);
+            userPK.setDomainId(domainId);
+            (new UserRepository()).delete(userPK);
+
+            UserGroupPK userGroupPK = new UserGroupPK();
+            userGroupPK.setGroupId(userId);
+            userGroupPK.setDomainId(domainId);
+            (new UserGroupRepository()).delete(userGroupPK);
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public User getUser(String domainId, String userId) throws SharingRegistryException, TException {
+        try{
+            UserPK userPK = new UserPK();
+            userPK.setUserId(userId);
+            userPK.setDomainId(domainId);
+            return (new UserRepository()).get(userPK);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public List<User> getUsers(String domain, int offset, int limit) throws SharingRegistryException, TException {
+        try{
+            HashMap<String, String> filters = new HashMap<>();
+            filters.put(DBConstants.UserTable.DOMAIN_ID, domain);
+            return (new UserRepository()).select(filters, offset, limit);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    /**
+     * * Group Operations
+     * *
+     */
+    @Override
+    public String createGroup(UserGroup group) throws SharingRegistryException, TException {
+        try{
+            UserGroupPK userGroupPK = new UserGroupPK();
+            userGroupPK.setGroupId(group.getGroupId());
+            userGroupPK.setDomainId(group.getDomainId());
+            if((new UserGroupRepository()).get(userGroupPK) != null)
+                throw new SharingRegistryException("There exist group with given group id");
+            //Client created groups are always of type MULTI_USER
+            group.setGroupCardinality(GroupCardinality.MULTI_USER);
+            group.setCreatedTime(System.currentTimeMillis());
+            group.setUpdatedTime(System.currentTimeMillis());
+            //Add group admins once the group is created
+            group.unsetGroupAdmins();
+            (new UserGroupRepository()).create(group);
+
+            addUsersToGroup(group.getDomainId(), Arrays.asList(group.getOwnerId()), group.getGroupId());
+            return group.getGroupId();
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean updateGroup(UserGroup group) throws SharingRegistryException, TException {
+        try{
+            group.setUpdatedTime(System.currentTimeMillis());
+            UserGroupPK userGroupPK = new UserGroupPK();
+            userGroupPK.setGroupId(group.getGroupId());
+            userGroupPK.setDomainId(group.getDomainId());
+            UserGroup oldGroup = (new UserGroupRepository()).get(userGroupPK);
+            group.setGroupCardinality(oldGroup.getGroupCardinality());
+            group.setCreatedTime(oldGroup.getCreatedTime());
+            group = getUpdatedObject(oldGroup, group);
+
+            if(!group.getOwnerId().equals(oldGroup.getOwnerId()))
+                throw new SharingRegistryException("Group owner cannot be changed");
+
+            (new UserGroupRepository()).update(group);
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    /**
+     * API method to check Group Exists
+     * @param domainId
+     * @param groupId
+     * @return
+     * @throws SharingRegistryException
+     * @throws TException
+     */
+    @Override
+    public boolean isGroupExists(String domainId, String groupId) throws SharingRegistryException, TException {
+        try{
+            UserGroupPK userGroupPK = new UserGroupPK();
+            userGroupPK.setDomainId(domainId);
+            userGroupPK.setGroupId(groupId);
+            return (new UserGroupRepository()).isExists(userGroupPK);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean deleteGroup(String domainId, String groupId) throws SharingRegistryException, TException {
+        try{
+            UserGroupPK userGroupPK = new UserGroupPK();
+            userGroupPK.setGroupId(groupId);
+            userGroupPK.setDomainId(domainId);
+            (new UserGroupRepository()).delete(userGroupPK);
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public UserGroup getGroup(String domainId, String groupId) throws SharingRegistryException, TException {
+        try{
+            UserGroupPK userGroupPK = new UserGroupPK();
+            userGroupPK.setGroupId(groupId);
+            userGroupPK.setDomainId(domainId);
+            return (new UserGroupRepository()).get(userGroupPK);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public List<UserGroup> getGroups(String domain, int offset, int limit) throws TException {
+        try{
+            HashMap<String, String> filters = new HashMap<>();
+            filters.put(DBConstants.UserGroupTable.DOMAIN_ID, domain);
+            // Only return groups with MULTI_USER cardinality which is the only type of cardinality allowed for client created groups
+            filters.put(DBConstants.UserGroupTable.GROUP_CARDINALITY, GroupCardinality.MULTI_USER.name());
+            return (new UserGroupRepository()).select(filters, offset, limit);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean addUsersToGroup(String domainId, List<String> userIds, String groupId) throws SharingRegistryException, TException {
+        try{
+            for(int i=0; i < userIds.size(); i++){
+                GroupMembership groupMembership = new GroupMembership();
+                groupMembership.setParentId(groupId);
+                groupMembership.setChildId(userIds.get(i));
+                groupMembership.setChildType(GroupChildType.USER);
+                groupMembership.setDomainId(domainId);
+                groupMembership.setCreatedTime(System.currentTimeMillis());
+                groupMembership.setUpdatedTime(System.currentTimeMillis());
+                (new GroupMembershipRepository()).create(groupMembership);
+            }
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean removeUsersFromGroup(String domainId, List<String> userIds, String groupId) throws SharingRegistryException, TException {
+        try{
+            for (String userId: userIds) {
+                if (hasOwnerAccess(domainId, groupId, userId)) {
+                    throw new SharingRegistryException("List of User Ids contains Owner Id. Cannot remove owner from the group");
+                }
+            }
+
+            for(int i=0; i < userIds.size(); i++){
+                GroupMembershipPK groupMembershipPK = new GroupMembershipPK();
+                groupMembershipPK.setParentId(groupId);
+                groupMembershipPK.setChildId(userIds.get(i));
+                groupMembershipPK.setDomainId(domainId);
+                (new GroupMembershipRepository()).delete(groupMembershipPK);
+            }
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean transferGroupOwnership(String domainId, String groupId, String newOwnerId) throws SharingRegistryException, TException {
+        try {
+            List<User> groupUser = getGroupMembersOfTypeUser(domainId, groupId, 0, -1);
+            if (!isUserBelongsToGroup(groupUser, newOwnerId)) {
+                throw new SharingRegistryException("New group owner is not part of the group");
+            }
+
+            if (hasOwnerAccess(domainId, groupId, newOwnerId)) {
+                throw new DuplicateEntryException("User already the current owner of the group");
+            }
+            // remove the new owner as Admin if present
+            if (hasAdminAccess(domainId, groupId, newOwnerId)) {
+                removeGroupAdmins(domainId, groupId, Arrays.asList(newOwnerId));
+            }
+
+            UserGroupPK userGroupPK = new UserGroupPK();
+            userGroupPK.setGroupId(groupId);
+            userGroupPK.setDomainId(domainId);
+            UserGroup userGroup = (new UserGroupRepository()).get(userGroupPK);
+            UserGroup newUserGroup = new UserGroup();
+            newUserGroup.setUpdatedTime(System.currentTimeMillis());
+            newUserGroup.setOwnerId(newOwnerId);
+            newUserGroup.setGroupCardinality(GroupCardinality.MULTI_USER);
+            newUserGroup.setCreatedTime(userGroup.getCreatedTime());
+            newUserGroup = getUpdatedObject(userGroup, newUserGroup);
+
+            (new UserGroupRepository()).update(newUserGroup);
+
+            return true;
+        }
+        catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    private boolean isUserBelongsToGroup(List<User> groupUser, String newOwnerId) {
+        for (User user: groupUser) {
+            if (user.getUserId().equals(newOwnerId)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean addGroupAdmins(String domainId, String groupId, List<String> adminIds) throws SharingRegistryException, TException {
+        try{
+            List<User> groupUser = getGroupMembersOfTypeUser(domainId, groupId, 0, -1);
+
+            for (String adminId: adminIds) {
+                if (! isUserBelongsToGroup(groupUser, adminId)) {
+                    throw new SharingRegistryException("Admin not the user of the group. GroupId : "+ groupId + ", AdminId : "+ adminId);
+                }
+                GroupAdminPK groupAdminPK = new GroupAdminPK();
+                groupAdminPK.setGroupId(groupId);
+                groupAdminPK.setAdminId(adminId);
+                groupAdminPK.setDomainId(domainId);
+
+                if((new GroupAdminRepository()).get(groupAdminPK) != null)
+                    throw new DuplicateEntryException("User already an admin for the group");
+
+                GroupAdmin admin = new GroupAdmin();
+                admin.setAdminId(adminId);
+                admin.setDomainId(domainId);
+                admin.setGroupId(groupId);
+                (new GroupAdminRepository()).create(admin);
+            }
+            return true;
+        }
+        catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean removeGroupAdmins(String domainId, String groupId, List<String> adminIds) throws SharingRegistryException, TException {
+        try {
+            for (String adminId: adminIds) {
+                GroupAdminPK groupAdminPK = new GroupAdminPK();
+                groupAdminPK.setAdminId(adminId);
+                groupAdminPK.setDomainId(domainId);
+                groupAdminPK.setGroupId(groupId);
+                (new GroupAdminRepository()).delete(groupAdminPK);
+            }
+            return true;
+        }
+        catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean hasAdminAccess(String domainId, String groupId, String adminId) throws SharingRegistryException, TException {
+        try{
+            GroupAdminPK groupAdminPK = new GroupAdminPK();
+            groupAdminPK.setGroupId(groupId);
+            groupAdminPK.setAdminId(adminId);
+            groupAdminPK.setDomainId(domainId);
+
+            if((new GroupAdminRepository()).get(groupAdminPK) != null)
+                return true;
+            return false;
+        }
+        catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean hasOwnerAccess(String domainId, String groupId, String ownerId) throws SharingRegistryException, TException {
+        try {
+            UserGroupPK userGroupPK = new UserGroupPK();
+            userGroupPK.setGroupId(groupId);
+            userGroupPK.setDomainId(domainId);
+            UserGroup getGroup = (new UserGroupRepository()).get(userGroupPK);
+
+            if(getGroup.getOwnerId().equals(ownerId))
+                return true;
+            return false;
+        }
+        catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public List<User> getGroupMembersOfTypeUser(String domainId, String groupId, int offset, int limit) throws SharingRegistryException, TException {
+        try{
+            //TODO limit offset
+            List<User> groupMemberUsers = (new GroupMembershipRepository()).getAllChildUsers(domainId, groupId);
+            return groupMemberUsers;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public List<UserGroup> getGroupMembersOfTypeGroup(String domainId, String groupId, int offset, int limit) throws SharingRegistryException, TException {
+        try{
+            //TODO limit offset
+            List<UserGroup> groupMemberGroups = (new GroupMembershipRepository()).getAllChildGroups(domainId, groupId);
+            return groupMemberGroups;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean addChildGroupsToParentGroup(String domainId, List<String> childIds, String groupId) throws SharingRegistryException, TException {
+        try{
+            for(String childId : childIds) {
+                //Todo check for cyclic dependencies
+                GroupMembership groupMembership = new GroupMembership();
+                groupMembership.setParentId(groupId);
+                groupMembership.setChildId(childId);
+                groupMembership.setChildType(GroupChildType.GROUP);
+                groupMembership.setDomainId(domainId);
+                groupMembership.setCreatedTime(System.currentTimeMillis());
+                groupMembership.setUpdatedTime(System.currentTimeMillis());
+                (new GroupMembershipRepository()).create(groupMembership);
+            }
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean removeChildGroupFromParentGroup(String domainId, String childId, String groupId) throws SharingRegistryException, TException {
+        try{
+            GroupMembershipPK groupMembershipPK = new GroupMembershipPK();
+            groupMembershipPK.setParentId(groupId);
+            groupMembershipPK.setChildId(childId);
+            groupMembershipPK.setDomainId(domainId);
+            (new GroupMembershipRepository()).delete(groupMembershipPK);
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public List<UserGroup> getAllMemberGroupsForUser(String domainId, String userId) throws SharingRegistryException, TException {
+        try{
+            GroupMembershipRepository groupMembershipRepository = new GroupMembershipRepository();
+            return groupMembershipRepository.getAllMemberGroupsForUser(domainId, userId);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    /**
+     * * EntityType Operations
+     * *
+     */
+    @Override
+    public String createEntityType(EntityType entityType) throws SharingRegistryException, DuplicateEntryException, TException {
+        try{
+            EntityTypePK entityTypePK = new EntityTypePK();
+            entityTypePK.setDomainId(entityType.getDomainId());
+            entityTypePK.setEntityTypeId(entityType.getEntityTypeId());
+            if((new EntityTypeRepository()).get(entityTypePK) != null)
+                throw new DuplicateEntryException("There exist EntityType with given EntityType id");
+
+            entityType.setCreatedTime(System.currentTimeMillis());
+            entityType.setUpdatedTime(System.currentTimeMillis());
+            (new EntityTypeRepository()).create(entityType);
+            return entityType.getEntityTypeId();
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean updateEntityType(EntityType entityType) throws SharingRegistryException, TException {
+        try{
+            entityType.setUpdatedTime(System.currentTimeMillis());
+            EntityTypePK entityTypePK = new EntityTypePK();
+            entityTypePK.setDomainId(entityType.getDomainId());
+            entityTypePK.setEntityTypeId(entityType.getEntityTypeId());
+            EntityType oldEntityType = (new EntityTypeRepository()).get(entityTypePK);
+            entityType.setCreatedTime(oldEntityType.getCreatedTime());
+            entityType = getUpdatedObject(oldEntityType, entityType);
+            (new EntityTypeRepository()).update(entityType);
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    /**
+     * <p>API method to check EntityType Exists</p>
+     *
+     * @param entityTypeId
+     */
+    @Override
+    public boolean isEntityTypeExists(String domainId, String entityTypeId) throws SharingRegistryException, TException {
+        try{
+            EntityTypePK entityTypePK = new EntityTypePK();
+            entityTypePK.setDomainId(domainId);
+            entityTypePK.setEntityTypeId(entityTypeId);
+            return (new EntityTypeRepository()).isExists(entityTypePK);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean deleteEntityType(String domainId, String entityTypeId) throws SharingRegistryException, TException {
+        try{
+            EntityTypePK entityTypePK = new EntityTypePK();
+            entityTypePK.setDomainId(domainId);
+            entityTypePK.setEntityTypeId(entityTypeId);
+            (new EntityTypeRepository()).delete(entityTypePK);
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public EntityType getEntityType(String domainId, String entityTypeId) throws SharingRegistryException, TException {
+        try{
+            EntityTypePK entityTypePK = new EntityTypePK();
+            entityTypePK.setDomainId(domainId);
+            entityTypePK.setEntityTypeId(entityTypeId);
+            return (new EntityTypeRepository()).get(entityTypePK);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public List<EntityType> getEntityTypes(String domain, int offset, int limit) throws TException {
+        try{
+            HashMap<String, String> filters = new HashMap<>();
+            filters.put(DBConstants.EntityTypeTable.DOMAIN_ID, domain);
+            return (new EntityTypeRepository()).select(filters, offset, limit);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    /**
+     * * Permission Operations
+     * *
+     */
+    @Override
+    public String createPermissionType(PermissionType permissionType) throws SharingRegistryException, DuplicateEntryException, TException {
+        try{
+            PermissionTypePK permissionTypePK =  new PermissionTypePK();
+            permissionTypePK.setDomainId(permissionType.getDomainId());
+            permissionTypePK.setPermissionTypeId(permissionType.getPermissionTypeId());
+            if((new PermissionTypeRepository()).get(permissionTypePK) != null)
+                throw new DuplicateEntryException("There exist PermissionType with given PermissionType id");
+            permissionType.setCreatedTime(System.currentTimeMillis());
+            permissionType.setUpdatedTime(System.currentTimeMillis());
+            (new PermissionTypeRepository()).create(permissionType);
+            return permissionType.getPermissionTypeId();
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean updatePermissionType(PermissionType permissionType) throws SharingRegistryException, TException {
+        try{
+            permissionType.setUpdatedTime(System.currentTimeMillis());
+            PermissionTypePK permissionTypePK =  new PermissionTypePK();
+            permissionTypePK.setDomainId(permissionType.getDomainId());
+            permissionTypePK.setPermissionTypeId(permissionType.getPermissionTypeId());
+            PermissionType oldPermissionType = (new PermissionTypeRepository()).get(permissionTypePK);
+            permissionType = getUpdatedObject(oldPermissionType, permissionType);
+            (new PermissionTypeRepository()).update(permissionType);
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    /**
+     * <p>API method to check Permission Exists</p>
+     *
+     * @param permissionId
+     */
+    @Override
+    public boolean isPermissionExists(String domainId, String permissionId) throws SharingRegistryException, TException {
+        try{
+            PermissionTypePK permissionTypePK = new PermissionTypePK();
+            permissionTypePK.setDomainId(domainId);
+            permissionTypePK.setPermissionTypeId(permissionId);
+            return (new PermissionTypeRepository()).isExists(permissionTypePK);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean deletePermissionType(String domainId, String permissionTypeId) throws SharingRegistryException, TException {
+        try{
+            PermissionTypePK permissionTypePK =  new PermissionTypePK();
+            permissionTypePK.setDomainId(domainId);
+            permissionTypePK.setPermissionTypeId(permissionTypeId);
+            (new PermissionTypeRepository()).delete(permissionTypePK);
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public PermissionType getPermissionType(String domainId, String permissionTypeId) throws SharingRegistryException, TException {
+        try{
+            PermissionTypePK permissionTypePK =  new PermissionTypePK();
+            permissionTypePK.setDomainId(domainId);
+            permissionTypePK.setPermissionTypeId(permissionTypeId);
+            return (new PermissionTypeRepository()).get(permissionTypePK);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public List<PermissionType> getPermissionTypes(String domain, int offset, int limit) throws SharingRegistryException, TException {
+        try{
+            HashMap<String, String> filters = new HashMap<>();
+            filters.put(DBConstants.PermissionTypeTable.DOMAIN_ID, domain);
+            return (new PermissionTypeRepository()).select(filters, offset, limit);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    /**
+     * * Entity Operations
+     * *
+     */
+    @Override
+    public String createEntity(Entity entity) throws SharingRegistryException, DuplicateEntryException, TException {
+        try{
+            EntityPK entityPK = new EntityPK();
+            entityPK.setDomainId(entity.getDomainId());
+            entityPK.setEntityId(entity.getEntityId());
+            if((new EntityRepository()).get(entityPK) != null)
+                throw new DuplicateEntryException("There exist Entity with given Entity id");
+
+            UserPK userPK = new UserPK();
+            userPK.setDomainId(entity.getDomainId());
+            userPK.setUserId(entity.getOwnerId());
+            if(!(new UserRepository()).isExists(userPK)){
+                //Todo this is for Airavata easy integration. Proper thing is to throw an exception here
+                User user = new User();
+                user.setUserId(entity.getOwnerId());
+                user.setDomainId(entity.getDomainId());
+                user.setUserName(user.getUserId().split("@")[0]);
+
+                createUser(user);
+            }
+            entity.setCreatedTime(System.currentTimeMillis());
+            entity.setUpdatedTime(System.currentTimeMillis());
+
+            if(entity.getOriginalEntityCreationTime()==0){
+                entity.setOriginalEntityCreationTime(entity.getCreatedTime());
+            }
+            (new EntityRepository()).create(entity);
+
+            //Assigning global permission for the owner
+            Sharing newSharing = new Sharing();
+            newSharing.setPermissionTypeId((new PermissionTypeRepository()).getOwnerPermissionTypeIdForDomain(entity.getDomainId()));
+            newSharing.setEntityId(entity.getEntityId());
+            newSharing.setGroupId(entity.getOwnerId());
+            newSharing.setSharingType(SharingType.DIRECT_CASCADING);
+            newSharing.setInheritedParentId(entity.getEntityId());
+            newSharing.setDomainId(entity.getDomainId());
+            newSharing.setCreatedTime(System.currentTimeMillis());
+            newSharing.setUpdatedTime(System.currentTimeMillis());
+
+            (new SharingRepository()).create(newSharing);
+
+            // creating records for inherited permissions
+            if (entity.getParentEntityId() != null && entity.getParentEntityId() != "") {
+                addCascadingPermissionsForEntity(entity);
+            }
+
+            return entity.getEntityId();
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            SharingRegistryException sharingRegistryException = new SharingRegistryException();
+            sharingRegistryException.setMessage(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+            throw sharingRegistryException;
+        }
+    }
+
+    private void addCascadingPermissionsForEntity(Entity entity) throws SharingRegistryException {
+        Sharing newSharing;
+        List<Sharing> sharings = (new SharingRepository()).getCascadingPermissionsForEntity(entity.getDomainId(),
+                entity.getParentEntityId());
+        for (Sharing sharing : sharings) {
+                    newSharing = new Sharing();
+                    newSharing.setPermissionTypeId(sharing.getPermissionTypeId());
+                    newSharing.setEntityId(entity.getEntityId());
+                    newSharing.setGroupId(sharing.getGroupId());
+                    newSharing.setInheritedParentId(sharing.getInheritedParentId());
+                    newSharing.setSharingType(SharingType.INDIRECT_CASCADING);
+                    newSharing.setDomainId(entity.getDomainId());
+                    newSharing.setCreatedTime(System.currentTimeMillis());
+                    newSharing.setUpdatedTime(System.currentTimeMillis());
+
+                    (new SharingRepository()).create(newSharing);
+                }
+            }
+
+    @Override
+    public boolean updateEntity(Entity entity) throws SharingRegistryException, TException {
+        try{
+            //TODO Check for permission changes
+            entity.setUpdatedTime(System.currentTimeMillis());
+            EntityPK entityPK = new EntityPK();
+            entityPK.setDomainId(entity.getDomainId());
+            entityPK.setEntityId(entity.getEntityId());
+            Entity oldEntity = (new EntityRepository()).get(entityPK);
+            entity.setCreatedTime(oldEntity.getCreatedTime());
+            // check if parent entity changed and re-add inherited permissions
+            if (!Objects.equals(oldEntity.getParentEntityId(), entity.getParentEntityId())) {
+                logger.debug("Parent entity changed for {}, updating inherited permissions", entity.getEntityId());
+                if (oldEntity.getParentEntityId() != null && oldEntity.getParentEntityId() != "") {
+                    logger.debug("Removing inherited permissions from {} that were inherited from parent {}", entity.getEntityId(), oldEntity.getParentEntityId());
+                    (new SharingRepository()).removeAllIndirectCascadingPermissionsForEntity(entity.getDomainId(), entity.getEntityId());
+                }
+                if (entity.getParentEntityId() != null && entity.getParentEntityId() != "") {
+                    // re-add INDIRECT_CASCADING permissions
+                    logger.debug("Adding inherited permissions to {} that are inherited from parent {}", entity.getEntityId(), entity.getParentEntityId());
+                    addCascadingPermissionsForEntity(entity);
+                }
+            }
+            entity = getUpdatedObject(oldEntity, entity);
+            entity.setSharedCount((new SharingRepository()).getSharedCount(entity.getDomainId(), entity.getEntityId()));
+            (new EntityRepository()).update(entity);
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    /**
+     * <p>API method to check Entity Exists</p>
+     *
+     * @param entityId
+     */
+    @Override
+    public boolean isEntityExists(String domainId, String entityId) throws SharingRegistryException, TException {
+        try{
+            EntityPK entityPK = new EntityPK();
+            entityPK.setDomainId(domainId);
+            entityPK.setEntityId(entityId);
+            return (new EntityRepository()).isExists(entityPK);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean deleteEntity(String domainId, String entityId) throws SharingRegistryException, TException {
+        try{
+            //TODO Check for permission changes
+            EntityPK entityPK = new EntityPK();
+            entityPK.setDomainId(domainId);
+            entityPK.setEntityId(entityId);
+            (new EntityRepository()).delete(entityPK);
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public Entity getEntity(String domainId, String entityId) throws SharingRegistryException, TException {
+        try{
+            EntityPK entityPK = new EntityPK();
+            entityPK.setDomainId(domainId);
+            entityPK.setEntityId(entityId);
+            return (new EntityRepository()).get(entityPK);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public List<Entity> searchEntities(String domainId, String userId, List<SearchCriteria> filters,
+                                       int offset, int limit) throws SharingRegistryException, TException {
+        try{
+            List<String> groupIds = new ArrayList<>();
+            groupIds.add(userId);
+            (new GroupMembershipRepository()).getAllParentMembershipsForChild(domainId, userId).stream().forEach(gm -> groupIds.add(gm.getParentId()));
+            return (new EntityRepository()).searchEntities(domainId, groupIds, filters, offset, limit);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public List<User> getListOfSharedUsers(String domainId, String entityId, String permissionTypeId) throws SharingRegistryException, TException {
+        try{
+            return (new UserRepository()).getAccessibleUsers(domainId, entityId, permissionTypeId);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public List<User> getListOfDirectlySharedUsers(String domainId, String entityId, String permissionTypeId)
+            throws SharingRegistryException, TException {
+        try{
+            return (new UserRepository()).getDirectlyAccessibleUsers(domainId, entityId, permissionTypeId);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            SharingRegistryException sharingRegistryException = new SharingRegistryException();
+            sharingRegistryException.setMessage(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+            throw sharingRegistryException;
+        }
+    }
+
+    @Override
+    public List<UserGroup> getListOfSharedGroups(String domainId, String entityId, String permissionTypeId) throws SharingRegistryException, TException {
+        try{
+            return (new UserGroupRepository()).getAccessibleGroups(domainId, entityId, permissionTypeId);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public List<UserGroup> getListOfDirectlySharedGroups(String domainId, String entityId, String permissionTypeId)
+            throws SharingRegistryException, TException {
+        try{
+            return (new UserGroupRepository()).getDirectlyAccessibleGroups(domainId, entityId, permissionTypeId);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            SharingRegistryException sharingRegistryException = new SharingRegistryException();
+            sharingRegistryException.setMessage(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+            throw sharingRegistryException;
+        }
+    }
+
+    /**
+     * Sharing Entity with Users and Groups
+     * @param domainId
+     * @param entityId
+     * @param userList
+     * @param permissionTypeId
+     * @param cascadePermission
+     * @return
+     * @throws SharingRegistryException
+     * @throws TException
+     */
+    @Override
+    public boolean shareEntityWithUsers(String domainId, String entityId, List<String> userList, String permissionTypeId, boolean cascadePermission) throws SharingRegistryException, TException {
+        try{
+            return shareEntity(domainId, entityId, userList, permissionTypeId, cascadePermission);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean shareEntityWithGroups(String domainId, String entityId, List<String> groupList, String permissionTypeId, boolean cascadePermission) throws SharingRegistryException, TException {
+        try{
+            return shareEntity(domainId, entityId, groupList, permissionTypeId, cascadePermission);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    private boolean shareEntity(String domainId, String entityId, List<String> groupOrUserList, String permissionTypeId, boolean cascadePermission)  throws SharingRegistryException, TException {
+        try{
+            if(permissionTypeId.equals((new PermissionTypeRepository()).getOwnerPermissionTypeIdForDomain(domainId))){
+                throw new SharingRegistryException(OWNER_PERMISSION_NAME + " permission cannot be assigned or removed");
+            }
+
+            List<Sharing> sharings = new ArrayList<>();
+
+            //Adding permission for the specified users/groups for the specified entity
+            LinkedList<Entity> temp = new LinkedList<>();
+            for(String userId : groupOrUserList){
+                Sharing sharing = new Sharing();
+                sharing.setPermissionTypeId(permissionTypeId);
+                sharing.setEntityId(entityId);
+                sharing.setGroupId(userId);
+                sharing.setInheritedParentId(entityId);
+                sharing.setDomainId(domainId);
+                if(cascadePermission) {
+                    sharing.setSharingType(SharingType.DIRECT_CASCADING);
+                }else {
+                    sharing.setSharingType(SharingType.DIRECT_NON_CASCADING);
+                }
+                sharing.setCreatedTime(System.currentTimeMillis());
+                sharing.setUpdatedTime(System.currentTimeMillis());
+
+                sharings.add(sharing);
+            }
+
+            if(cascadePermission){
+                //Adding permission for the specified users/groups for all child entities
+                (new EntityRepository()).getChildEntities(domainId, entityId).stream().forEach(e -> temp.addLast(e));
+                while(temp.size() > 0){
+                    Entity entity = temp.pop();
+                    String childEntityId = entity.getEntityId();
+                    for(String userId : groupOrUserList){
+                        Sharing sharing = new Sharing();
+                        sharing.setPermissionTypeId(permissionTypeId);
+                        sharing.setEntityId(childEntityId);
+                        sharing.setGroupId(userId);
+                        sharing.setInheritedParentId(entityId);
+                        sharing.setSharingType(SharingType.INDIRECT_CASCADING);
+                        sharing.setInheritedParentId(entityId);
+                        sharing.setDomainId(domainId);
+                        sharing.setCreatedTime(System.currentTimeMillis());
+                        sharing.setUpdatedTime(System.currentTimeMillis());
+                        sharings.add(sharing);
+                        (new EntityRepository()).getChildEntities(domainId, childEntityId).stream().forEach(e -> temp.addLast(e));
+                    }
+                }
+            }
+            (new SharingRepository()).create(sharings);
+
+            EntityPK entityPK = new EntityPK();
+            entityPK.setDomainId(domainId);
+            entityPK.setEntityId(entityId);
+            Entity entity = (new EntityRepository()).get(entityPK);
+            entity.setSharedCount((new SharingRepository()).getSharedCount(domainId, entityId));
+            (new EntityRepository()).update(entity);
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean revokeEntitySharingFromUsers(String domainId, String entityId, List<String> userList, String permissionTypeId) throws SharingRegistryException, TException {
+        try{
+            if(permissionTypeId.equals((new PermissionTypeRepository()).getOwnerPermissionTypeIdForDomain(domainId))){
+                throw new SharingRegistryException(OWNER_PERMISSION_NAME + " permission cannot be assigned or removed");
+            }
+            return revokeEntitySharing(domainId, entityId, userList, permissionTypeId);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+
+    @Override
+    public boolean revokeEntitySharingFromGroups(String domainId, String entityId, List<String> groupList, String permissionTypeId) throws SharingRegistryException, TException {
+        try{
+            if(permissionTypeId.equals((new PermissionTypeRepository()).getOwnerPermissionTypeIdForDomain(domainId))){
+                throw new SharingRegistryException(OWNER_PERMISSION_NAME + " permission cannot be assigned or removed");
+            }
+            return revokeEntitySharing(domainId, entityId, groupList, permissionTypeId);
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    @Override
+    public boolean userHasAccess(String domainId, String userId, String entityId, String permissionTypeId) throws SharingRegistryException, TException {
+        try{
+            //check whether the user has permission directly or indirectly
+            List<GroupMembership> parentMemberships = (new GroupMembershipRepository()).getAllParentMembershipsForChild(domainId, userId);
+            List<String> groupIds = new ArrayList<>();
+            parentMemberships.stream().forEach(pm->groupIds.add(pm.getParentId()));
+            groupIds.add(userId);
+            return (new SharingRepository()).hasAccess(domainId, entityId, groupIds, Arrays.asList(permissionTypeId,
+                    (new PermissionTypeRepository()).getOwnerPermissionTypeIdForDomain(domainId)));
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+    }
+
+    public boolean revokeEntitySharing(String domainId, String entityId, List<String> groupOrUserList, String permissionTypeId) throws SharingRegistryException {
+        try{
+            if(permissionTypeId.equals((new PermissionTypeRepository()).getOwnerPermissionTypeIdForDomain(domainId))){
+                throw new SharingRegistryException(OWNER_PERMISSION_NAME + " permission cannot be removed");
+            }
+
+            //revoking permission for the entity
+            for(String groupId : groupOrUserList){
+                SharingPK sharingPK = new SharingPK();
+                sharingPK.setEntityId(entityId);
+                sharingPK.setGroupId(groupId);
+                sharingPK.setPermissionTypeId(permissionTypeId);
+                sharingPK.setInheritedParentId(entityId);
+                sharingPK.setDomainId(domainId);
+
+                (new SharingRepository()).delete(sharingPK);
+            }
+
+            //revoking permission from inheritance
+            List<Sharing> temp = new ArrayList<>();
+            (new SharingRepository()).getIndirectSharedChildren(domainId, entityId, permissionTypeId).stream().forEach(s -> temp.add(s));
+            for(Sharing sharing : temp){
+                String childEntityId = sharing.getEntityId();
+                for(String groupId : groupOrUserList){
+                    SharingPK sharingPK = new SharingPK();
+                    sharingPK.setEntityId(childEntityId);
+                    sharingPK.setGroupId(groupId);
+                    sharingPK.setPermissionTypeId(permissionTypeId);
+                    sharingPK.setInheritedParentId(entityId);
+                    sharingPK.setDomainId(domainId);
+
+                    (new SharingRepository()).delete(sharingPK);
+                }
+            }
+
+            EntityPK entityPK = new EntityPK();
+            entityPK.setDomainId(domainId);
+            entityPK.setEntityId(entityId);
+            Entity entity = (new EntityRepository()).get(entityPK);
+            entity.setSharedCount((new SharingRepository()).getSharedCount(domainId, entityId));
+            (new EntityRepository()).update(entity);
+            return true;
+        }catch (Throwable ex) {
+            logger.error(ex.getMessage(), ex);
+            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
+        }
+
+    }
+
+
+
+    private <T> T getUpdatedObject(T oldEntity, T newEntity) throws SharingRegistryException {
+        Field[] newEntityFields = newEntity.getClass().getDeclaredFields();
+        Hashtable newHT = fieldsToHT(newEntityFields, newEntity);
+
+        Class oldEntityClass = oldEntity.getClass();
+        Field[] oldEntityFields = oldEntityClass.getDeclaredFields();
+
+        for (Field field : oldEntityFields){
+            if (!Modifier.isFinal(field.getModifiers())) {
+                field.setAccessible(true);
+                Object o = newHT.get(field.getName());
+                if (o != null) {
+                    Field f = null;
+                    try {
+                        f = oldEntityClass.getDeclaredField(field.getName());
+                        f.setAccessible(true);
+                        logger.debug("setting " + f.getName());
+                        f.set(oldEntity, o);
+                    } catch (Exception e) {
+                        throw new SharingRegistryException(e.getMessage());
+                    }
+                }
+            }
+        }
+        return oldEntity;
+    }
+
+    private static Hashtable<String, Object> fieldsToHT(Field[] fields, Object obj){
+        Hashtable<String,Object> hashtable = new Hashtable<>();
+        for (Field field: fields){
+            field.setAccessible(true);
+            try {
+                Object retrievedObject = field.get(obj);
+                if (retrievedObject != null){
+                    logger.debug("scanning " + field.getName());
+                    hashtable.put(field.getName(), field.get(obj));
+                }
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            }
+        }
+        return hashtable;
+    }
+
+}
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/resources/META-INF/persistence.xml b/custos-sharing-registry-service/sharing-registry-server/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000..936b84d
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
+
+    <persistence-unit name="airavata-sharing-registry">
+        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
+        <class>org.apache.airavata.sharing.registry.db.entities.DomainEntity</class>
+        <class>org.apache.airavata.sharing.registry.db.entities.EntityEntity</class>
+        <class>org.apache.airavata.sharing.registry.db.entities.EntityTypeEntity</class>
+        <class>org.apache.airavata.sharing.registry.db.entities.GroupMembershipEntity</class>
+        <class>org.apache.airavata.sharing.registry.db.entities.PermissionTypeEntity</class>
+        <class>org.apache.airavata.sharing.registry.db.entities.SharingEntity</class>
+        <class>org.apache.airavata.sharing.registry.db.entities.UserEntity</class>
+        <class>org.apache.airavata.sharing.registry.db.entities.GroupAdminEntity</class>
+        <class>org.apache.airavata.sharing.registry.db.entities.UserGroupEntity</class>
+    </persistence-unit>
+</persistence>
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/resources/airavata.jks b/custos-sharing-registry-service/sharing-registry-server/src/main/resources/airavata.jks
new file mode 100644
index 0000000..e0e46e2
Binary files /dev/null and b/custos-sharing-registry-service/sharing-registry-server/src/main/resources/airavata.jks differ
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/resources/client_truststore.jks b/custos-sharing-registry-service/sharing-registry-server/src/main/resources/client_truststore.jks
new file mode 100644
index 0000000..4ff588f
Binary files /dev/null and b/custos-sharing-registry-service/sharing-registry-server/src/main/resources/client_truststore.jks differ
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/resources/sharing-registry-derby.sql b/custos-sharing-registry-service/sharing-registry-server/src/main/resources/sharing-registry-derby.sql
new file mode 100644
index 0000000..a7038e2
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/resources/sharing-registry-derby.sql
@@ -0,0 +1,147 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+CREATE TABLE DOMAIN (
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  NAME VARCHAR(255) NOT NULL,
+  DESCRIPTION VARCHAR(255),
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (DOMAIN_ID)
+);
+
+CREATE TABLE SHARING_USER (
+  USER_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  USER_NAME VARCHAR(255) NOT NULL,
+  FIRST_NAME VARCHAR (255),
+  LAST_NAME VARCHAR (255),
+  EMAIL VARCHAR (255),
+  ICON BLOB,
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (USER_ID, DOMAIN_ID),
+  FOREIGN KEY (DOMAIN_ID) REFERENCES DOMAIN(DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+);
+
+CREATE TABLE GROUP_ADMIN (
+  ADMIN_ID VARCHAR(255) NOT NULL,
+  GROUP_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  PRIMARY KEY (ADMIN_ID, GROUP_ID, DOMAIN_ID),
+  FOREIGN KEY (ADMIN_ID, DOMAIN_ID) REFERENCES SHARING_USER(USER_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+);
+
+CREATE TABLE USER_GROUP (
+  GROUP_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  NAME VARCHAR(255) NOT NULL,
+  DESCRIPTION VARCHAR(255),
+  OWNER_ID VARCHAR(255) NOT NULL,
+  GROUP_TYPE VARCHAR(255) NOT NULL,
+  GROUP_CARDINALITY VARCHAR(255) NOT NULL,
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (GROUP_ID, DOMAIN_ID),
+  FOREIGN KEY (OWNER_ID, DOMAIN_ID) REFERENCES SHARING_USER(USER_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+);
+
+
+CREATE TABLE GROUP_MEMBERSHIP (
+  PARENT_ID VARCHAR(255) NOT NULL,
+  CHILD_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  CHILD_TYPE VARCHAR(255) NOT NULL,
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (PARENT_ID, CHILD_ID, DOMAIN_ID),
+  FOREIGN KEY (PARENT_ID, DOMAIN_ID) REFERENCES USER_GROUP(GROUP_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION,
+  FOREIGN KEY (CHILD_ID, DOMAIN_ID) REFERENCES USER_GROUP(GROUP_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+);
+
+CREATE TABLE ENTITY_TYPE (
+  ENTITY_TYPE_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  NAME VARCHAR(255) NOT NULL,
+  DESCRIPTION VARCHAR(255),
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (ENTITY_TYPE_ID, DOMAIN_ID),
+  FOREIGN KEY (DOMAIN_ID) REFERENCES DOMAIN(DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+);
+
+CREATE TABLE PERMISSION_TYPE (
+  PERMISSION_TYPE_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  NAME VARCHAR(255) NOT NULL,
+  DESCRIPTION VARCHAR(255),
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (PERMISSION_TYPE_ID, DOMAIN_ID),
+  FOREIGN KEY (DOMAIN_ID) REFERENCES DOMAIN(DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+);
+
+CREATE TABLE ENTITY (
+  ENTITY_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  ENTITY_TYPE_ID VARCHAR(255) NOT NULL,
+  OWNER_ID VARCHAR(255) NOT NULL,
+  PARENT_ENTITY_ID VARCHAR(255),
+  NAME VARCHAR(255) NOT NULL,
+  DESCRIPTION VARCHAR(255),
+  BINARY_DATA BLOB,
+  FULL_TEXT VARCHAR(255),
+  SHARED_COUNT BIGINT DEFAULT 0,
+  ORIGINAL_ENTITY_CREATION_TIME BIGINT NOT NULL,
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (ENTITY_ID, DOMAIN_ID),
+  FOREIGN KEY (ENTITY_TYPE_ID, DOMAIN_ID) REFERENCES ENTITY_TYPE(ENTITY_TYPE_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION,
+  FOREIGN KEY (OWNER_ID, DOMAIN_ID) REFERENCES SHARING_USER(USER_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION,
+  FOREIGN KEY (PARENT_ENTITY_ID, DOMAIN_ID) REFERENCES ENTITY(ENTITY_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+);
+
+-- ALTER TABLE ENTITY ADD FULLTEXT FULL_TEXT_INDEX(FULL_TEXT);
+
+CREATE TABLE SHARING (
+  PERMISSION_TYPE_ID VARCHAR(255) NOT NULL,
+  ENTITY_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR (255) NOT NULL,
+  GROUP_ID VARCHAR(255) NOT NULL,
+  SHARING_TYPE VARCHAR(255) NOT NULL,
+  INHERITED_PARENT_ID VARCHAR(255),
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (PERMISSION_TYPE_ID, ENTITY_ID, GROUP_ID, DOMAIN_ID, INHERITED_PARENT_ID),
+  FOREIGN KEY (PERMISSION_TYPE_ID, DOMAIN_ID) REFERENCES PERMISSION_TYPE(PERMISSION_TYPE_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION,
+  FOREIGN KEY (ENTITY_ID, DOMAIN_ID) REFERENCES ENTITY(ENTITY_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION,
+  FOREIGN KEY (INHERITED_PARENT_ID, DOMAIN_ID) REFERENCES ENTITY(ENTITY_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION,
+  FOREIGN KEY (GROUP_ID, DOMAIN_ID) REFERENCES USER_GROUP(GROUP_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+);
+
+CREATE TABLE CONFIGURATION
+(
+  CONFIG_KEY VARCHAR(255) NOT NULL,
+  CONFIG_VALUE VARCHAR(255) NOT NULL,
+  PRIMARY KEY(CONFIG_KEY, CONFIG_VALUE)
+);
+
+INSERT INTO CONFIGURATION (CONFIG_KEY, CONFIG_VALUE) VALUES('sharing_reg_version', '0.17');
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/main/resources/sharing-registry-mysql.sql b/custos-sharing-registry-service/sharing-registry-server/src/main/resources/sharing-registry-mysql.sql
new file mode 100644
index 0000000..145d926
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/main/resources/sharing-registry-mysql.sql
@@ -0,0 +1,146 @@
+/*
+ *
+ * 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.
+ *
+*/
+
+CREATE TABLE DOMAIN (
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  NAME VARCHAR(255) NOT NULL,
+  DESCRIPTION VARCHAR(255),
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (DOMAIN_ID)
+)ENGINE=InnoDB DEFAULT CHARACTER SET=latin1;
+
+CREATE TABLE SHARING_USER (
+  USER_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  USER_NAME VARCHAR(255) NOT NULL,
+  FIRST_NAME VARCHAR (255),
+  LAST_NAME VARCHAR (255),
+  EMAIL VARCHAR (255),
+  ICON BLOB,
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (USER_ID, DOMAIN_ID),
+  FOREIGN KEY (DOMAIN_ID) REFERENCES DOMAIN(DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+)ENGINE=InnoDB DEFAULT CHARACTER SET=latin1;
+
+CREATE TABLE USER_GROUP (
+  GROUP_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  NAME VARCHAR(255) NOT NULL,
+  DESCRIPTION VARCHAR(255),
+  OWNER_ID VARCHAR(255) NOT NULL,
+  GROUP_TYPE VARCHAR(255) NOT NULL,
+  GROUP_CARDINALITY VARCHAR(255) NOT NULL,
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (GROUP_ID, DOMAIN_ID),
+  FOREIGN KEY (OWNER_ID, DOMAIN_ID) REFERENCES SHARING_USER(USER_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+)ENGINE=InnoDB DEFAULT CHARACTER SET=latin1;
+
+CREATE TABLE GROUP_ADMIN (
+  ADMIN_ID VARCHAR(255) NOT NULL,
+  GROUP_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  PRIMARY KEY (ADMIN_ID, GROUP_ID, DOMAIN_ID),
+  FOREIGN KEY (ADMIN_ID, DOMAIN_ID) REFERENCES SHARING_USER(USER_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+)ENGINE=InnoDB DEFAULT CHARACTER SET=latin1;
+
+CREATE TABLE GROUP_MEMBERSHIP (
+  PARENT_ID VARCHAR(255) NOT NULL,
+  CHILD_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  CHILD_TYPE VARCHAR(255) NOT NULL,
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (PARENT_ID, CHILD_ID, DOMAIN_ID),
+  FOREIGN KEY (PARENT_ID, DOMAIN_ID) REFERENCES USER_GROUP(GROUP_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION,
+  FOREIGN KEY (CHILD_ID, DOMAIN_ID) REFERENCES USER_GROUP(GROUP_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+)ENGINE=InnoDB DEFAULT CHARACTER SET=latin1;
+
+CREATE TABLE ENTITY_TYPE (
+  ENTITY_TYPE_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  NAME VARCHAR(255) NOT NULL,
+  DESCRIPTION VARCHAR(255),
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (ENTITY_TYPE_ID, DOMAIN_ID),
+  FOREIGN KEY (DOMAIN_ID) REFERENCES DOMAIN(DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+)ENGINE=InnoDB DEFAULT CHARACTER SET=latin1;
+
+CREATE TABLE PERMISSION_TYPE (
+  PERMISSION_TYPE_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  NAME VARCHAR(255) NOT NULL,
+  DESCRIPTION VARCHAR(255),
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (PERMISSION_TYPE_ID, DOMAIN_ID),
+  FOREIGN KEY (DOMAIN_ID) REFERENCES DOMAIN(DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+)ENGINE=InnoDB DEFAULT CHARACTER SET=latin1;
+
+CREATE TABLE ENTITY (
+  ENTITY_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR(255) NOT NULL,
+  ENTITY_TYPE_ID VARCHAR(255) NOT NULL,
+  OWNER_ID VARCHAR(255) NOT NULL,
+  PARENT_ENTITY_ID VARCHAR(255),
+  NAME VARCHAR(255) NOT NULL,
+  DESCRIPTION VARCHAR(255),
+  BINARY_DATA BLOB,
+  FULL_TEXT TEXT,
+  SHARED_COUNT BIGINT DEFAULT 0,
+  ORIGINAL_ENTITY_CREATION_TIME BIGINT NOT NULL,
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (ENTITY_ID, DOMAIN_ID),
+  FOREIGN KEY (ENTITY_TYPE_ID, DOMAIN_ID) REFERENCES ENTITY_TYPE(ENTITY_TYPE_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION,
+  FOREIGN KEY (OWNER_ID, DOMAIN_ID) REFERENCES SHARING_USER(USER_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION,
+  FOREIGN KEY (PARENT_ENTITY_ID, DOMAIN_ID) REFERENCES ENTITY(ENTITY_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+)ENGINE=InnoDB DEFAULT CHARACTER SET=latin1;
+
+ALTER TABLE ENTITY ADD FULLTEXT FULL_TEXT_INDEX(FULL_TEXT);
+
+CREATE TABLE SHARING (
+  PERMISSION_TYPE_ID VARCHAR(255) NOT NULL,
+  ENTITY_ID VARCHAR(255) NOT NULL,
+  DOMAIN_ID VARCHAR (255) NOT NULL,
+  GROUP_ID VARCHAR(255) NOT NULL,
+  SHARING_TYPE VARCHAR(255) NOT NULL,
+  INHERITED_PARENT_ID VARCHAR(255),
+  CREATED_TIME BIGINT NOT NULL,
+  UPDATED_TIME BIGINT NOT NULL,
+  PRIMARY KEY (PERMISSION_TYPE_ID, ENTITY_ID, GROUP_ID, DOMAIN_ID, INHERITED_PARENT_ID),
+  CONSTRAINT `SHARING_PERMISSION_TYPE_ID_DOMAIN_ID_FK` FOREIGN KEY (PERMISSION_TYPE_ID, DOMAIN_ID) REFERENCES PERMISSION_TYPE(PERMISSION_TYPE_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION,
+  CONSTRAINT `SHARING_ENTITY_ID_DOMAIN_ID_FK` FOREIGN KEY (ENTITY_ID, DOMAIN_ID) REFERENCES ENTITY(ENTITY_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION,
+  CONSTRAINT `SHARING_INHERITED_PARENT_ID_DOMAIN_ID_FK` FOREIGN KEY (INHERITED_PARENT_ID, DOMAIN_ID) REFERENCES ENTITY(ENTITY_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION,
+  CONSTRAINT `SHARING_GROUP_ID_DOMAIN_ID_FK` FOREIGN KEY (GROUP_ID, DOMAIN_ID) REFERENCES USER_GROUP(GROUP_ID, DOMAIN_ID) ON DELETE CASCADE ON UPDATE NO ACTION
+)ENGINE=InnoDB DEFAULT CHARACTER SET=latin1;
+
+CREATE TABLE CONFIGURATION
+(
+  CONFIG_KEY VARCHAR(255) NOT NULL,
+  CONFIG_VALUE VARCHAR(255) NOT NULL,
+  PRIMARY KEY(CONFIG_KEY, CONFIG_VALUE)
+)ENGINE=InnoDB DEFAULT CHARACTER SET=latin1;
+
+INSERT INTO CONFIGURATION (CONFIG_KEY, CONFIG_VALUE) VALUES('sharing_reg_version', '0.17');
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/test/java/org/apache/custos/sharing/registry/CipresTest.java b/custos-sharing-registry-service/sharing-registry-server/src/test/java/org/apache/custos/sharing/registry/CipresTest.java
new file mode 100644
index 0000000..f3ccc52
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/test/java/org/apache/custos/sharing/registry/CipresTest.java
@@ -0,0 +1,632 @@
+/**
+ *
+ * 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.custos.sharing.registry;
+
+import org.apache.custos.commons.exceptions.ApplicationSettingsException;
+import org.apache.custos.commons.utils.ServerSettings;
+import org.apache.custos.sharing.registry.models.*;
+import org.apache.custos.sharing.registry.service.cpi.SharingRegistryService;
+import org.apache.thrift.TException;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.protocol.TProtocol;
+import org.apache.thrift.transport.TSSLTransportFactory;
+import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TTransportException;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class CipresTest {
+    public static void main(String[] args) throws InterruptedException, TException, ApplicationSettingsException {
+        System.out.println("Hello World!");
+        //should use the correct host name and port here
+        String serverHost = "wb-airavata.scigap.org";
+
+        int serverPort = 7878;
+        TTransport transport = null;
+        TProtocol protocol = null;
+        try {
+
+            SharingRegistryService.Client sharingServiceClient;
+
+            //Non Secure Client
+//            transport = new TSocket(serverHost, serverPort);
+//            transport.open();
+//            protocol = new TBinaryProtocol(transport);
+//            sharingServiceClient= new SharingRegistryService.Client(protocol);
+
+            //TLS enabled client
+            TSSLTransportFactory.TSSLTransportParameters params =
+                    new TSSLTransportFactory.TSSLTransportParameters();
+            params.setKeyStore(ServerSettings.getKeyStorePath(), ServerSettings.getKeyStorePassword());
+            params.setTrustStore(ServerSettings.getTrustStorePath(), ServerSettings.getTrustStorePassword());
+            transport = TSSLTransportFactory.getClientSocket(serverHost, serverPort, 10000, params);
+            protocol = new TBinaryProtocol(transport);
+            sharingServiceClient = new SharingRegistryService.Client(protocol);
+
+
+            try {
+                sharingServiceClient.deleteDomain("test-domain");
+            } catch (SharingRegistryException sre1) {
+                System.out.println("deleteDomain failed" + sre1.getMessage() + "\n");
+            }
+            Domain domain = new Domain();
+            //has to be one word
+            domain.setName("test-domain");
+            //optional
+            domain.setDescription("test domain description");
+            //domain id will be same as domain name
+            String domainId = sharingServiceClient.createDomain(domain);
+            System.out.println("After domain creation...\n");
+
+            User user1 = new User();
+            String userName1 = "test-user-1";
+            String userId1 = "test-user-1";
+            //required
+            user1.setUserId(userId1);
+            //required
+            user1.setUserName(userName1);
+            //required
+            user1.setDomainId(domainId);
+            //required
+            user1.setFirstName("John");
+            //required
+            user1.setLastName("Doe");
+            //required
+            user1.setEmail("john.doe@abc.com");
+            //optional - this should be bytes of the users image icon
+            //byte[] icon = new byte[10];
+            //user1.setIcon(icon);
+            sharingServiceClient.createUser(user1);
+            User user2 = new User();
+            String userName2 = "test-user-2";
+            String userId2 = "test-user-2";
+            //required
+            user2.setUserId(userId2);
+            //required
+            user2.setUserName(userName2);
+            //required
+            user2.setDomainId(domainId);
+            //required
+            user2.setFirstName("John");
+            //required
+            user2.setLastName("Doe");
+            //required
+            user2.setEmail("john.doe@abc.com");
+            //optional - this should be bytes of the users image icon
+            //byte[] icon = new byte[20];
+            //user2.setIcon(icon);
+            sharingServiceClient.createUser(user2);
+            User user3 = new User();
+            String userName3 = "test-user-3";
+            String userId3 = "test-user-3";
+            //required
+            user3.setUserId(userId3);
+            //required
+            user3.setUserName(userName3);
+            //required
+            user3.setDomainId(domainId);
+            //required
+            user3.setFirstName("John");
+            //required
+            user3.setLastName("Doe");
+            //required
+            user3.setEmail("john.doe@abc.com");
+            //optional - this should be bytes of the users image icon
+            //byte[] icon = new byte[30];
+            //user3.setIcon(icon);
+            sharingServiceClient.createUser(user3);
+            System.out.println("After user creation...\n");
+
+            UserGroup userGroup1 = new UserGroup();
+            //required
+            userGroup1.setGroupId("test-group-1");
+            //required
+            userGroup1.setDomainId(domainId);
+            //required
+            userGroup1.setName("test-group-1");
+            //optional
+            //userGroup1.setDescription("test group description");
+            //required
+            userGroup1.setOwnerId("test-user-1");
+            //required
+            userGroup1.setGroupType(GroupType.USER_LEVEL_GROUP);
+            sharingServiceClient.createGroup(userGroup1);
+            //Similarly create another group "userGroup2" with the owner being "test-user-2".
+            UserGroup userGroup2 = new UserGroup();
+            //required
+            userGroup2.setGroupId("test-group-2");
+            //required
+            userGroup2.setDomainId(domainId);
+            //required
+            userGroup2.setName("test-group-2");
+            //optional
+            //userGroup2.setDescription("test group description");
+            //required
+            userGroup2.setOwnerId("test-user-2");
+            //required
+            userGroup2.setGroupType(GroupType.USER_LEVEL_GROUP);
+            sharingServiceClient.createGroup(userGroup2);
+            System.out.println("After group creation...\n");
+
+            sharingServiceClient.addUsersToGroup(domainId, Arrays.asList("test-user-3"), "test-group-2");
+            System.out.println("After adding user to group...\n");
+
+            sharingServiceClient.addChildGroupsToParentGroup(domainId, Arrays.asList("test-group-2"), "test-group-1");
+
+
+            PermissionType permissionType1 = new PermissionType();
+            //required
+            permissionType1.setPermissionTypeId("READ");
+            //required
+            permissionType1.setDomainId(domainId);
+            //required
+            permissionType1.setName("READ");
+            //optional
+            permissionType1.setDescription("READ description");
+            sharingServiceClient.createPermissionType(permissionType1);
+            PermissionType permissionType2 = new PermissionType();
+            permissionType2.setPermissionTypeId("WRITE");
+            permissionType2.setDomainId(domainId);
+            permissionType2.setName("WRITE");
+            permissionType2.setDescription("WRITE description");
+            sharingServiceClient.createPermissionType(permissionType2);
+            PermissionType permissionType3 = new PermissionType();
+            permissionType3.setPermissionTypeId("CLONE");
+            permissionType3.setDomainId(domainId);
+            permissionType3.setName("CLONE");
+            permissionType3.setDescription("CLONE description");
+            sharingServiceClient.createPermissionType(permissionType3);
+            System.out.println("After adding groups to parent group...\n");
+
+            EntityType entityType1 = new EntityType();
+            //required
+            entityType1.setEntityTypeId("PROJECT");
+            //required
+            entityType1.setDomainId(domainId);
+            //required
+            entityType1.setName("PROJECT");
+            //optional
+            entityType1.setDescription("PROJECT entity type description");
+            sharingServiceClient.createEntityType(entityType1);
+            EntityType entityType2 = new EntityType();
+            entityType2.setEntityTypeId("EXPERIMENT");
+            entityType2.setDomainId(domainId);
+            entityType2.setName("EXPERIMENT");
+            entityType2.setDescription("EXPERIMENT entity type");
+            sharingServiceClient.createEntityType(entityType2);
+            EntityType entityType3 = new EntityType();
+            entityType3.setEntityTypeId("FILE");
+            entityType3.setDomainId(domainId);
+            entityType3.setName("FILE");
+            entityType3.setDescription("FILE entity type");
+            sharingServiceClient.createEntityType(entityType3);
+            System.out.println("After project entity creation...\n");
+
+            Entity entity1 = new Entity();
+            //required
+            entity1.setEntityId("test-project-1");
+            //required
+            entity1.setDomainId(domainId);
+            //required
+            entity1.setEntityTypeId("PROJECT");
+            //required
+            entity1.setOwnerId("test-user-1");
+            //required
+            entity1.setName("test-project-1");
+            //optional
+            entity1.setDescription("test project 1 description");
+            //optional
+            entity1.setFullText("test project 1 stampede gaussian seagrid");
+            //optional - If not set this will be default to current system time
+            entity1.setOriginalEntityCreationTime(System.currentTimeMillis());
+            sharingServiceClient.createEntity(entity1);
+            System.out.println("After currentTimeMillis()...\n");
+            Entity entity2 = new Entity();
+            entity2.setEntityId("test-experiment-1");
+            entity2.setDomainId(domainId);
+            entity2.setEntityTypeId("EXPERIMENT");
+            entity2.setOwnerId("test-user-1");
+            entity2.setName("test-experiment-1");
+            entity2.setDescription("test experiment 1 description");
+            entity2.setParentEntityId("test-project-1");
+            entity2.setFullText("test experiment 1 benzene");
+            System.out.println("Before sharingServiceClient.createEntity entity2...\n");
+            sharingServiceClient.createEntity(entity2);
+            System.out.println("After sharingServiceClient.createEntity entity2...\n");
+            Entity entity3 = new Entity();
+            entity3.setEntityId("test-experiment-2");
+            entity3.setDomainId(domainId);
+            entity3.setEntityTypeId("EXPERIMENT");
+            entity3.setOwnerId("test-user-1");
+            entity3.setName("test-experiment-2");
+            entity3.setDescription("test experiment 2 description");
+            entity3.setParentEntityId("test-project-1");
+            entity3.setFullText("test experiment 1 3-methyl 1-butanol stampede");
+            sharingServiceClient.createEntity(entity3);
+            System.out.println("After sharingServiceClient.createEntity entity3...\n");
+            Entity entity4 = new Entity();
+            entity4.setEntityId("test-file-1");
+            entity4.setDomainId(domainId);
+            entity4.setEntityTypeId("FILE");
+            entity4.setOwnerId("test-user-1");
+            entity4.setName("test-file-1");
+            entity4.setDescription("test file 1 description");
+            entity4.setParentEntityId("test-experiment-2");
+            entity4.setFullText("test input file 1 for experiment 2");
+            sharingServiceClient.createEntity(entity4);
+            System.out.println("After sharingServiceClient.createEntity entity4...\n");
+            System.out.println("After test entity creation...\n");
+
+            //shared with cascading permissions
+            //System.out.println("Before shareEntityWithUsers WRITE...\n");
+            //sharingServiceClient.shareEntityWithUsers(domainId, "test-project-1", Arrays.asList("test-user-2"), "WRITE", true);
+            System.out.println("Before shareEntityWithGroups READ...\n");
+            long time = System.currentTimeMillis();
+            sharingServiceClient.shareEntityWithGroups(domainId, "test-experiment-2", Arrays.asList("test-group-2"), "READ", true);
+            System.out.println("Time for sharing " + (System.currentTimeMillis() - time));
+            //shared with non cascading permissions
+            System.out.println("Before shareEntityWithGroups CLONE...\n");
+            time = System.currentTimeMillis();
+            sharingServiceClient.shareEntityWithGroups(domainId, "test-experiment-2", Arrays.asList("test-group-2"), "CLONE", false);
+            System.out.println("Time for sharing " + (System.currentTimeMillis() - time));
+
+            //test-project-1 is explicitly shared with test-user-2 with WRITE permission
+            System.out.println("Before userHasAccess 1...\n");
+            System.out.println(sharingServiceClient.userHasAccess(domainId, "test-user-2", "test-project-1", "WRITE"));
+            //test-user-2 has WRITE permission to test-experiment-1 and test-experiment-2 indirectly
+            System.out.println("Before userHasAccess 2...\n");
+            System.out.println(sharingServiceClient.userHasAccess(domainId, "test-user-2", "test-experiment-1", "WRITE"));
+            System.out.println("Before userHasAccess 3...\n");
+            System.out.println(sharingServiceClient.userHasAccess(domainId, "test-user-2", "test-experiment-2", "WRITE"));
+            //test-user-2 does not have READ permission to test-experiment-1 and test-experiment-2
+            System.out.println("Before userHasAccess 4...\n");
+            System.out.println(sharingServiceClient.userHasAccess(domainId, "test-user-2", "test-experiment-1", "READ"));
+            System.out.println(domainId + " test-user-2 " + " test-experiment-2 " + " READ ");
+            System.out.println("Before userHasAccess 5...\n");
+            System.out.println(sharingServiceClient.userHasAccess(domainId, "test-user-2", "test-experiment-2", "READ"));
+            //test-user-3 does not have READ permission to test-project-1
+            System.out.println("Before userHasAccess 6...\n");
+            System.out.println(sharingServiceClient.userHasAccess(domainId, "test-user-3", "test-project-1", "READ"));
+            //test-experiment-2 is shared with test-group-2 with READ permission. Therefore test-user-3 has READ permission
+            System.out.println("Before userHasAccess 7...\n");
+            System.out.println(sharingServiceClient.userHasAccess(domainId, "test-user-3", "test-experiment-2", "READ"));
+            //test-user-3 does not have WRITE permission to test-experiment-2
+            System.out.println("Before userHasAccess 8...\n");
+            System.out.println(sharingServiceClient.userHasAccess(domainId, "test-user-3", "test-experiment-2", "WRITE"));
+            //test-user-3 has CLONE permission to test-experiment-2
+            System.out.println("Before userHasAccess 9...\n");
+            System.out.println((sharingServiceClient.userHasAccess(domainId, "test-user-3", "test-experiment-2", "CLONE")));
+            //test-user-3 does not have CLONE permission to test-file-1
+            System.out.println("Before userHasAccess 10...\n");
+            System.out.println((sharingServiceClient.userHasAccess(domainId, "test-user-3", "test-file-1", "CLONE")));
+            System.out.println("After cascading permissions...\n");
+
+            ArrayList<SearchCriteria> filters = new ArrayList<>();
+            //ArrayList<SearchCriteria> filters = new List<>();
+            SearchCriteria searchCriteria = new SearchCriteria();
+            searchCriteria.setSearchCondition(SearchCondition.LIKE);
+            searchCriteria.setValue("experiment stampede methyl");
+            //searchCriteria.setValue("stampede");
+            //searchCriteria.setSearchField(EntitySearchField.NAME);
+            searchCriteria.setSearchField(EntitySearchField.FULL_TEXT);
+            filters.add(searchCriteria);
+            searchCriteria = new SearchCriteria();
+            searchCriteria.setSearchCondition(SearchCondition.EQUAL);
+            searchCriteria.setValue("READ");
+            searchCriteria.setSearchField(EntitySearchField.PERMISSION_TYPE_ID);
+            filters.add(searchCriteria);
+            System.out.println(sharingServiceClient.searchEntities(domainId, "test-user-2", filters, 0, -1).size());
+            System.out.println(sharingServiceClient.searchEntities(domainId, "test-user-2", filters, 0, -1));
+            System.out.println("After searchEntities...\n");
+
+
+            //System.out.println("After searchEntities...\n");
+            User userA = new User();
+            String userNameA = "UserA";
+            String userIdA = "UserA";
+            //required
+            userA.setUserId(userIdA);
+            //required
+            userA.setUserName(userNameA);
+            //required
+            userA.setDomainId(domainId);
+            //required
+            userA.setFirstName("User");
+            //required
+            userA.setLastName("A");
+            //required
+            userA.setEmail("user.a@example.com");
+            //optional - this should be bytes of the users image icon
+            //byte[] icon = new byte[10];
+            //userA.setIcon(icon);
+            sharingServiceClient.createUser(userA);
+            User userB = new User();
+            String userNameB = "UserB";
+            String userIdB = "UserB";
+            //required
+            userB.setUserId(userIdB);
+            //required
+            userB.setUserName(userNameB);
+            //required
+            userB.setDomainId(domainId);
+            //required
+            userB.setFirstName("User");
+            //required
+            userB.setLastName("B");
+            //required
+            userB.setEmail("user.b@example.com");
+            //optional - this should be bytes of the users image icon
+            //byte[] icon = new byte[10];
+            //userB.setIcon(icon);
+            sharingServiceClient.createUser(userB);
+            User userC = new User();
+            String userNameC = "UserC";
+            String userIdC = "UserC";
+            //required
+            userC.setUserId(userIdC);
+            //required
+            userC.setUserName(userNameC);
+            //required
+            userC.setDomainId(domainId);
+            //required
+            userC.setFirstName("User");
+            //required
+            userC.setLastName("C");
+            //required
+            userC.setEmail("user.c@example.com");
+            //optional - this should be bytes of the users image icon
+            //byte[] icon = new byte[10];
+            //userC.setIcon(icon);
+            sharingServiceClient.createUser(userC);
+            User userD = new User();
+            String userNameD = "UserD";
+            String userIdD = "UserD";
+            //required
+            userD.setUserId(userIdD);
+            //required
+            userD.setUserName(userNameD);
+            //required
+            userD.setDomainId(domainId);
+            //required
+            userD.setFirstName("User");
+            //required
+            userD.setLastName("D");
+            //required
+            userD.setEmail("user.d@example.com");
+            //optional - this should be bytes of the users image icon
+            //byte[] icon = new byte[10];
+            //userD.setIcon(icon);
+            sharingServiceClient.createUser(userD);
+            System.out.println("After user creation...\n");
+
+            UserGroup Group1 = new UserGroup();
+            //required
+            Group1.setGroupId("Group1");
+            //required
+            Group1.setDomainId(domainId);
+            //required
+            Group1.setName("Group1");
+            //optional
+            //userGroup1.setDescription("test group description");
+            //required
+            Group1.setOwnerId("UserA");
+            //required
+            Group1.setGroupType(GroupType.USER_LEVEL_GROUP);
+            sharingServiceClient.createGroup(Group1);
+            System.out.println("After Group1 creation...\n");
+
+            sharingServiceClient.addUsersToGroup(domainId, Arrays.asList("UserB"), "Group1");
+            sharingServiceClient.addUsersToGroup(domainId, Arrays.asList("UserC"), "Group1");
+            sharingServiceClient.addUsersToGroup(domainId, Arrays.asList("UserD"), "Group1");
+
+            System.out.println("After adding users to Group1 creation...\n");
+
+            EntityType entityTypeFolder = new EntityType();
+            //required
+            entityTypeFolder.setEntityTypeId("FOLDER");
+            //required
+            entityTypeFolder.setDomainId(domainId);
+            //required
+            entityTypeFolder.setName("FOLDER");
+            //optional
+            //entityTypeFolder.setDescription("PROJECT entity type description");
+            sharingServiceClient.createEntityType(entityTypeFolder);
+            System.out.println("After creating FOLDER entity type...\n");
+
+            EntityType entityTypeInputData = new EntityType();
+            //required
+            entityTypeInputData.setEntityTypeId("INPUTDATA");
+            //required
+            entityTypeInputData.setDomainId(domainId);
+            //required
+            entityTypeInputData.setName("INPUTDATA");
+            //optional
+            //entityTypeFolder.setDescription("PROJECT entity type description");
+            sharingServiceClient.createEntityType(entityTypeInputData);
+            System.out.println("After creating INPUTDATA entity type...\n");
+
+            Entity entityB1 = new Entity();
+            //required
+            entityB1.setEntityId("UserBProject1");
+            //required
+            entityB1.setDomainId(domainId);
+            //required
+            entityB1.setEntityTypeId("PROJECT");
+            //required
+            entityB1.setOwnerId("UserB");
+            //required
+            entityB1.setName("UserBProject1");
+            //optional
+            entityB1.setDescription("User B's Project 1");
+            //optional
+            entityB1.setFullText("test project 1");
+            //optional - If not set this will be default to current system time
+            entityB1.setOriginalEntityCreationTime(System.currentTimeMillis());
+            sharingServiceClient.createEntity(entityB1);
+            System.out.println("After creating UserBProject1 ...\n");
+
+            Entity entityC1 = new Entity();
+            //required
+            entityC1.setEntityId("UserCProject2");
+            //required
+            entityC1.setDomainId(domainId);
+            //required
+            entityC1.setEntityTypeId("PROJECT");
+            //required
+            entityC1.setOwnerId("UserC");
+            //required
+            entityC1.setName("UserCProject2");
+            //optional
+            entityC1.setDescription("User C's Project 2");
+            //optional
+            entityC1.setFullText("test project 2");
+            //optional - If not set this will be default to current system time
+            entityC1.setOriginalEntityCreationTime(System.currentTimeMillis());
+            sharingServiceClient.createEntity(entityC1);
+            System.out.println("After creating UserCProject2 ...\n");
+
+            Entity entityF1 = new Entity();
+            entityF1.setEntityId("Folder1");
+            entityF1.setDomainId(domainId);
+            entityF1.setEntityTypeId("FOLDER");
+            entityF1.setOwnerId("UserB");
+            entityF1.setName("UserBFolder1");
+            entityF1.setDescription("UserB's Folder 1");
+            entityF1.setParentEntityId("UserBProject1");
+            entityF1.setFullText("test experiment 1 ethidium");
+            sharingServiceClient.createEntity(entityF1);
+            System.out.println("After creating Folder1 ...\n");
+
+            Entity entityD1 = new Entity();
+            entityD1.setEntityId("Data1");
+            entityD1.setDomainId(domainId);
+            entityD1.setEntityTypeId("INPUTDATA");
+            entityD1.setOwnerId("UserB");
+            entityD1.setName("UserBData1");
+            entityD1.setDescription("UserB's Data 1");
+            entityD1.setParentEntityId("Folder1");
+            entityD1.setFullText("Data 1 for User B Folder 1");
+            sharingServiceClient.createEntity(entityD1);
+            System.out.println("After creating Data1 ...\n");
+
+            Entity entityF2 = new Entity();
+            entityF2.setEntityId("Folder2");
+            entityF2.setDomainId(domainId);
+            entityF2.setEntityTypeId("FOLDER");
+            entityF2.setOwnerId("UserC");
+            entityF2.setName("UserCFolder2");
+            entityF2.setDescription("UserC's Folder 2");
+            entityF2.setParentEntityId("UserCProject2");
+            entityF2.setFullText("test experiment 2 ethidium");
+            sharingServiceClient.createEntity(entityF2);
+            System.out.println("After creating Folder2 ...\n");
+
+            Entity entityD2 = new Entity();
+            entityD2.setEntityId("Data2");
+            entityD2.setDomainId(domainId);
+            entityD2.setEntityTypeId("INPUTDATA");
+            entityD2.setOwnerId("UserC");
+            entityD2.setName("UserCData2");
+            entityD2.setDescription("UserC's Data 2");
+            entityD2.setParentEntityId("Folder2");
+            entityD2.setFullText("Data 2 for User C Folder 1");
+            sharingServiceClient.createEntity(entityD2);
+            System.out.println("After creating Data2 ...\n");
+
+            //sharingServiceClient.shareEntityWithGroups(domainId, "test-experiment-2", Arrays.asList("test-group-2"), "READ", true);
+            time = System.currentTimeMillis();
+            sharingServiceClient.shareEntityWithGroups(domainId, "Folder1", Arrays.asList("Group1"), "READ", true);
+            System.out.println("Time for sharing " + (System.currentTimeMillis() - time));
+            System.out.println("After READ sharing UserBFolder1 with Group1 ...\n");
+            //sharingServiceClient.shareEntityWithGroups(domainId, "Folder2", Arrays.asList("Group1"), "READ", true);
+            //System.out.println("After READ sharing UserCFolder2 with Group1 ...\n");
+
+            Entity entityD3 = new Entity();
+            entityD3.setEntityId("Data3");
+            entityD3.setDomainId(domainId);
+            entityD3.setEntityTypeId("INPUTDATA");
+            entityD3.setOwnerId("UserC");
+            entityD3.setName("UserCData3");
+            entityD3.setDescription("UserC's Data 3");
+            entityD3.setParentEntityId("Folder2");
+            entityD3.setFullText("Data 3 for User C Folder 2");
+            sharingServiceClient.createEntity(entityD3);
+            System.out.println("After creating Data3 ...\n");
+
+            System.out.println("Does UserC have READ access to Data1 ...\n");
+            System.out.println(sharingServiceClient.userHasAccess(domainId, "UserC", "Data1", "READ"));
+            System.out.println("Does UserC have READ access to Data2 ...\n");
+            System.out.println(sharingServiceClient.userHasAccess(domainId, "UserC", "Data2", "READ"));
+            System.out.println("Does UserC have READ access to Data3 ...\n");
+            System.out.println(sharingServiceClient.userHasAccess(domainId, "UserC", "Data3", "READ"));
+            System.out.println("Does UserB have READ access to Data3 ...\n");
+            System.out.println(sharingServiceClient.userHasAccess(domainId, "UserB", "Data3", "READ"));
+
+            ArrayList<SearchCriteria> sharedfilters = new ArrayList<>();
+            searchCriteria = new SearchCriteria();
+            searchCriteria.setSearchCondition(SearchCondition.EQUAL);
+            searchCriteria.setValue("READ");
+            searchCriteria.setSearchField(EntitySearchField.PERMISSION_TYPE_ID);
+            sharedfilters.add(searchCriteria);
+            System.out.println("items READable by UserC ...\n");
+            System.out.println(sharingServiceClient.searchEntities(domainId, "UserC", sharedfilters, 0, -1).size());
+            System.out.println(sharingServiceClient.searchEntities(domainId, "UserC", sharedfilters, 0, -1));
+            searchCriteria = new SearchCriteria();
+            //searchCriteria.setSearchCondition(SearchCondition.EQUAL);
+            searchCriteria.setSearchCondition(SearchCondition.NOT);
+            searchCriteria.setValue("UserC");
+            searchCriteria.setSearchField(EntitySearchField.OWNER_ID);
+            sharedfilters.add(searchCriteria);
+            System.out.println("items READable, and not owned by UserC by UserC ...\n");
+            System.out.println(sharingServiceClient.searchEntities(domainId, "UserC", sharedfilters, 0, -1).size());
+            System.out.println(sharingServiceClient.searchEntities(domainId, "UserC", sharedfilters, 0, -1));
+            System.out.println("After searchEntities 2...\n");
+
+            System.out.println(sharingServiceClient.searchEntities(domainId, "UserC", sharedfilters, 0, -1).size());
+            System.out.println(sharingServiceClient.searchEntities(domainId, "UserC", sharedfilters, 0, -1));
+            System.out.println("After searchEntities 2...\n");
+
+
+            sharingServiceClient.removeUsersFromGroup(domainId, Arrays.asList("UserD"), "Group1");
+            System.out.println("After removing UserD from Group1 ...\n");
+
+            sharingServiceClient.deleteGroup(domainId, "Group1");
+            System.out.println("After deleting Group1 ...\n");
+
+            System.out.println("End of try clause...\n");
+        } catch (TTransportException ex1) {
+            System.out.println("TTransportException...\n");
+            System.out.println(ex1);
+            System.out.println(ex1.getCause());
+            ex1.printStackTrace();
+            System.out.println(ex1.getMessage());
+        } catch (SharingRegistryException ex2) {
+            System.out.println("SharingRegistryException...\n");
+            System.out.println(ex2.getMessage());
+        } catch (TException ex3) {
+            System.out.println("TException...\n");
+            System.out.println(ex3.getMessage());
+        } finally {
+            System.out.println("In finally...\n");
+            transport.close();
+        }
+    }
+}
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/test/java/org/apache/custos/sharing/registry/SharingRegistryServerHandlerTest.java b/custos-sharing-registry-service/sharing-registry-server/src/test/java/org/apache/custos/sharing/registry/SharingRegistryServerHandlerTest.java
new file mode 100644
index 0000000..2b88167
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/test/java/org/apache/custos/sharing/registry/SharingRegistryServerHandlerTest.java
@@ -0,0 +1,386 @@
+/**
+ *
+ * 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.custos.sharing.registry;
+
+import org.apache.custos.commons.exceptions.ApplicationSettingsException;
+import org.apache.custos.sharing.registry.db.utils.SharingRegistryDBInitConfig;
+import org.apache.custos.sharing.registry.models.*;
+import org.apache.custos.sharing.registry.server.SharingRegistryServerHandler;
+import org.junit.Assert;
+import org.apache.thrift.TException;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class SharingRegistryServerHandlerTest {
+    private final static Logger logger = LoggerFactory.getLogger(SharingRegistryServerHandlerTest.class);
+
+    @Test
+    public void test() throws TException, ApplicationSettingsException {
+        SharingRegistryDBInitConfig sharingRegistryDBInitConfig = new SharingRegistryDBInitConfig();
+        sharingRegistryDBInitConfig.setDBInitScriptPrefix("sharing-registry");
+        SharingRegistryServerHandler sharingRegistryServerHandler = new SharingRegistryServerHandler(sharingRegistryDBInitConfig);
+
+        //Creating domain
+        Domain domain = new Domain();
+        String domainId = "test-domain."+System.currentTimeMillis();
+        domain.setDomainId(domainId);
+        domain.setName(domainId);
+        domain.setDescription("test domain description");
+        domain.setCreatedTime(System.currentTimeMillis());
+        domain.setUpdatedTime(System.currentTimeMillis());
+
+        Assert.assertNotNull(sharingRegistryServerHandler.createDomain(domain));
+        Assert.assertTrue(sharingRegistryServerHandler.getDomains(0, 10).size() > 0);
+
+        //Creating users
+        User user1 = new User();
+        String userName1 = "test-user-1." + System.currentTimeMillis();
+        String userId1 = domainId + ":" + userName1;
+        user1.setUserId(userId1);
+        user1.setUserName(userName1);
+        user1.setDomainId(domainId);
+        user1.setCreatedTime(System.currentTimeMillis());
+        user1.setUpdatedTime(System.currentTimeMillis());
+
+        Assert.assertNotNull(sharingRegistryServerHandler.createUser(user1));
+
+        User user2 = new User();
+        String userName2 = "test-user-2." + System.currentTimeMillis();
+        String userId2 = domainId + ":" + userName2;
+        user2.setUserId(userId2);
+        user2.setUserName(userName2);
+        user2.setDomainId(domainId);
+        user2.setCreatedTime(System.currentTimeMillis());
+        user2.setUpdatedTime(System.currentTimeMillis());
+
+        Assert.assertNotNull(sharingRegistryServerHandler.createUser(user2));
+
+        User user3 = new User();
+        String userName3 = "test-user-3." + System.currentTimeMillis();
+        String userId3 = domainId + ":" + userName3;
+        user3.setUserId(userId3);
+        user3.setUserName(userName3);
+        user3.setDomainId(domainId);
+        user3.setCreatedTime(System.currentTimeMillis());
+        user3.setUpdatedTime(System.currentTimeMillis());
+
+        Assert.assertNotNull(sharingRegistryServerHandler.createUser(user3));
+
+        User user7 = new User();
+        String userName7 = "test-user-7." + System.currentTimeMillis();
+        String userId7 = domainId + ":" + userName7;
+        user7.setUserId(userId7);
+        user7.setUserName(userName7);
+        user7.setDomainId(domainId);
+        user7.setCreatedTime(System.currentTimeMillis());
+        user7.setUpdatedTime(System.currentTimeMillis());
+
+        Assert.assertNotNull(sharingRegistryServerHandler.createUser(user7));
+
+        Assert.assertTrue(sharingRegistryServerHandler.getUsers(domainId, 0, 10).size() > 0);
+
+        // Creating user groups
+        UserGroup userGroup1 = new UserGroup();
+        String groupName1 = "test-group-1." + System.currentTimeMillis();
+        String groupId1 = domainId + ":" + groupName1;
+        userGroup1.setGroupId(groupId1);
+        userGroup1.setDomainId(domainId);
+        userGroup1.setName(groupName1);
+        userGroup1.setDescription("test group description");
+        userGroup1.setOwnerId(userId1);
+        userGroup1.setGroupType(GroupType.USER_LEVEL_GROUP);
+        userGroup1.setGroupCardinality(GroupCardinality.MULTI_USER);
+        userGroup1.setCreatedTime(System.currentTimeMillis());
+        userGroup1.setUpdatedTime(System.currentTimeMillis());
+
+        Assert.assertNotNull(sharingRegistryServerHandler.createGroup(userGroup1));
+        Assert.assertEquals(1, sharingRegistryServerHandler.getAllMemberGroupsForUser(domainId, userId1).size());
+
+        UserGroup userGroup2 = new UserGroup();
+        String groupName2 = "test-group-2." + System.currentTimeMillis();
+        String groupId2 = domainId + ":" + groupName2;
+        userGroup2.setGroupId(groupId2);
+        userGroup2.setDomainId(domainId);
+        userGroup2.setName(groupName2);
+        userGroup2.setDescription("test group description");
+        userGroup2.setOwnerId(userId2);
+        userGroup2.setGroupType(GroupType.USER_LEVEL_GROUP);
+        userGroup2.setGroupCardinality(GroupCardinality.MULTI_USER);
+        userGroup2.setCreatedTime(System.currentTimeMillis());
+        userGroup2.setUpdatedTime(System.currentTimeMillis());
+
+        Assert.assertNotNull(sharingRegistryServerHandler.createGroup(userGroup2));
+
+        sharingRegistryServerHandler.addUsersToGroup(domainId, Arrays.asList(userId1), groupId1);
+        sharingRegistryServerHandler.addUsersToGroup(domainId, Arrays.asList(userId7), groupId1);
+
+        sharingRegistryServerHandler.addUsersToGroup(domainId, Arrays.asList(userId2, userId3), groupId2);
+        Assert.assertEquals(1, sharingRegistryServerHandler.getAllMemberGroupsForUser(domainId, userId3).size());
+
+        sharingRegistryServerHandler.addChildGroupsToParentGroup(domainId, Arrays.asList(groupId2), groupId1);
+
+        Assert.assertTrue(sharingRegistryServerHandler.getGroupMembersOfTypeGroup(domainId, groupId1, 0, 10).size() == 1);
+        Assert.assertTrue(sharingRegistryServerHandler.getGroupMembersOfTypeUser(domainId, groupId2, 0, 10).size() == 2);
+
+        // Group roles tests
+
+        // user has owner access
+        Assert.assertTrue(sharingRegistryServerHandler.hasOwnerAccess(domainId, groupId1, userId1));
+
+        // user has admin access
+        Assert.assertTrue(sharingRegistryServerHandler.addGroupAdmins(domainId, groupId1, Arrays.asList(userId7)));
+        Assert.assertTrue(sharingRegistryServerHandler.hasAdminAccess(domainId, groupId1, userId7));
+        Assert.assertTrue(sharingRegistryServerHandler.removeGroupAdmins(domainId, groupId1, Arrays.asList(userId7)));
+        Assert.assertFalse(sharingRegistryServerHandler.hasAdminAccess(domainId, groupId1, userId7));
+
+        // transfer group ownership
+        sharingRegistryServerHandler.addUsersToGroup(domainId, Arrays.asList(userId2), groupId1);
+        Assert.assertTrue(sharingRegistryServerHandler.transferGroupOwnership(domainId, groupId1, userId2));
+        Assert.assertTrue(sharingRegistryServerHandler.hasOwnerAccess(domainId, groupId1, userId2));
+        Assert.assertTrue(sharingRegistryServerHandler.transferGroupOwnership(domainId, groupId1, userId1));
+        Assert.assertFalse(sharingRegistryServerHandler.hasOwnerAccess(domainId, groupId1, userId2));
+
+        //Creating permission types
+        PermissionType permissionType1 = new PermissionType();
+        String permissionName1 = "READ";
+        permissionType1.setPermissionTypeId(domainId+":"+permissionName1);
+        permissionType1.setDomainId(domainId);
+        permissionType1.setName(permissionName1);
+        permissionType1.setDescription("READ description");
+        permissionType1.setCreatedTime(System.currentTimeMillis());
+        permissionType1.setUpdatedTime(System.currentTimeMillis());
+        String permissionTypeId1 = sharingRegistryServerHandler.createPermissionType(permissionType1);
+        Assert.assertNotNull(permissionTypeId1);
+
+        PermissionType permissionType2 = new PermissionType();
+        String permissionName2 = "WRITE";
+        permissionType2.setPermissionTypeId(domainId+":"+permissionName2);
+        permissionType2.setDomainId(domainId);
+        permissionType2.setName(permissionName2);
+        permissionType2.setDescription("WRITE description");
+        permissionType2.setCreatedTime(System.currentTimeMillis());
+        permissionType2.setUpdatedTime(System.currentTimeMillis());
+        String permissionTypeId2 = sharingRegistryServerHandler.createPermissionType(permissionType2);
+        Assert.assertNotNull(permissionTypeId2);
+
+        //Creating entity types
+        EntityType entityType1 = new EntityType();
+        String entityType1Name = "Project";
+        entityType1.setEntityTypeId(domainId+":"+entityType1Name);
+        entityType1.setDomainId(domainId);
+        entityType1.setName(entityType1Name);
+        entityType1.setDescription("test entity type");
+        entityType1.setCreatedTime(System.currentTimeMillis());
+        entityType1.setUpdatedTime(System.currentTimeMillis());
+        String entityTypeId1 = sharingRegistryServerHandler.createEntityType(entityType1);
+        Assert.assertNotNull(entityTypeId1);
+
+        EntityType entityType2 = new EntityType();
+        String entityType2Name = "Experiment";
+        entityType2.setEntityTypeId(domainId+":"+entityType2Name);
+        entityType2.setDomainId(domainId);
+        entityType2.setName(entityType2Name);
+        entityType2.setDescription("test entity type");
+        entityType2.setCreatedTime(System.currentTimeMillis());
+        entityType2.setUpdatedTime(System.currentTimeMillis());
+        String entityTypeId2 = sharingRegistryServerHandler.createEntityType(entityType2);
+        Assert.assertNotNull(entityTypeId2);
+
+        EntityType entityType3 = new EntityType();
+        String entityType3Name = "FileInput";
+        entityType3.setEntityTypeId(domainId+":"+entityType3Name);
+        entityType3.setDomainId(domainId);
+        entityType3.setName(entityType3Name);
+        entityType3.setDescription("file input type");
+        entityType3.setCreatedTime(System.currentTimeMillis());
+        entityType3.setUpdatedTime(System.currentTimeMillis());
+        String entityTypeId3 = sharingRegistryServerHandler.createEntityType(entityType3);
+        Assert.assertNotNull(entityTypeId3);
+
+        EntityType entityType4 = new EntityType();
+        String entityType4Name = "Application-Deployment";
+        entityType4.setEntityTypeId(domainId+":"+entityType4Name);
+        entityType4.setDomainId(domainId);
+        entityType4.setName(entityType4Name);
+        entityType4.setDescription("test entity type");
+        entityType4.setCreatedTime(System.currentTimeMillis());
+        entityType4.setUpdatedTime(System.currentTimeMillis());
+        String entityTypeId4 = sharingRegistryServerHandler.createEntityType(entityType4);
+        Assert.assertNotNull(entityTypeId4);
+
+        //Creating Entities
+        Entity entity1 = new Entity();
+        entity1.setEntityId(domainId+":Entity1");
+        entity1.setDomainId(domainId);
+        entity1.setEntityTypeId(entityTypeId1);
+        entity1.setOwnerId(userId1);
+        entity1.setName("Project name 1");
+        entity1.setDescription("Project description");
+        entity1.setFullText("Project name project description");
+        entity1.setCreatedTime(System.currentTimeMillis());
+        entity1.setUpdatedTime(System.currentTimeMillis());
+
+        String entityId1 = sharingRegistryServerHandler.createEntity(entity1);
+        Assert.assertNotNull(entityId1);
+
+        Entity entity2 = new Entity();
+        entity2.setEntityId(domainId+":Entity2");
+        entity2.setDomainId(domainId);
+        entity2.setEntityTypeId(entityTypeId2);
+        entity2.setOwnerId(userId1);
+        entity2.setName("Experiment name");
+        entity2.setDescription("Experiment description");
+        entity2.setParentEntityId(entityId1);
+        entity2.setFullText("Project name project description");
+        entity2.setCreatedTime(System.currentTimeMillis());
+        entity2.setUpdatedTime(System.currentTimeMillis());
+
+        String entityId2 = sharingRegistryServerHandler.createEntity(entity2);
+        Assert.assertNotNull(entityId2);
+
+        Entity entity3 = new Entity();
+        entity3.setEntityId(domainId+":Entity3");
+        entity3.setDomainId(domainId);
+        entity3.setEntityTypeId(entityTypeId2);
+        entity3.setOwnerId(userId1);
+        entity3.setName("Experiment name");
+        entity3.setDescription("Experiment description");
+        entity3.setParentEntityId(entityId1);
+        entity3.setFullText("Project name project description");
+        entity3.setCreatedTime(System.currentTimeMillis());
+        entity3.setUpdatedTime(System.currentTimeMillis());
+
+        String entityId3 = sharingRegistryServerHandler.createEntity(entity3);
+        Assert.assertNotNull(entityId3);
+
+        sharingRegistryServerHandler.shareEntityWithUsers(domainId, entityId1, Arrays.asList(userId2), permissionTypeId1, true);
+        sharingRegistryServerHandler.shareEntityWithGroups(domainId, entityId3, Arrays.asList(groupId2), permissionTypeId1, true);
+
+        Entity entity4 = new Entity();
+        entity4.setEntityId(domainId+":Entity4");
+        entity4.setDomainId(domainId);
+        entity4.setEntityTypeId(entityTypeId3);
+        entity4.setOwnerId(userId3);
+        entity4.setName("Input name");
+        entity4.setDescription("Input file description");
+        entity4.setParentEntityId(entityId3);
+        entity4.setFullText("Input File");
+        entity4.setCreatedTime(System.currentTimeMillis());
+        entity4.setUpdatedTime(System.currentTimeMillis());
+
+        String entityId4 = sharingRegistryServerHandler.createEntity(entity4);
+        Assert.assertNotNull(entityId4);
+
+        Assert.assertTrue(sharingRegistryServerHandler.userHasAccess(domainId, userId3, entityId4, permissionTypeId1));
+        Assert.assertTrue(sharingRegistryServerHandler.userHasAccess(domainId, userId2, entityId4, permissionTypeId1));
+        Assert.assertTrue(sharingRegistryServerHandler.userHasAccess(domainId, userId1, entityId4, permissionTypeId1));
+        Assert.assertFalse(sharingRegistryServerHandler.userHasAccess(domainId, userId3, entityId1, permissionTypeId1));
+
+        Entity entity5 = new Entity();
+        entity5.setEntityId(domainId+":Entity5");
+        entity5.setDomainId(domainId);
+        entity5.setEntityTypeId(entityTypeId4);
+        entity5.setOwnerId(userId1);
+        entity5.setName("App deployment name");
+        entity5.setDescription("App deployment description");
+        entity5.setFullText("App Deployment name app deployment description");
+        entity5.setCreatedTime(System.currentTimeMillis());
+        entity5.setUpdatedTime(System.currentTimeMillis());
+
+        String entityId5 = sharingRegistryServerHandler.createEntity(entity5);
+        Assert.assertNotNull(entityId5);
+
+        sharingRegistryServerHandler.shareEntityWithUsers(domainId, entityId5, Arrays.asList(userId2), permissionTypeId1, true);
+        sharingRegistryServerHandler.shareEntityWithGroups(domainId, entityId5, Arrays.asList(groupId2), permissionTypeId2, true);
+
+        Assert.assertTrue(sharingRegistryServerHandler.userHasAccess(domainId, userId3, entityId5, permissionTypeId2));
+        Assert.assertTrue(sharingRegistryServerHandler.userHasAccess(domainId, userId2, entityId5, permissionTypeId1));
+        Assert.assertFalse(sharingRegistryServerHandler.userHasAccess(domainId, userId3, entityId5, permissionTypeId1));
+
+        ArrayList<SearchCriteria> filters = new ArrayList<>();
+        SearchCriteria searchCriteria = new SearchCriteria();
+        searchCriteria.setSearchCondition(SearchCondition.LIKE);
+        searchCriteria.setValue("Input");
+        searchCriteria.setSearchField(EntitySearchField.NAME);
+        filters.add(searchCriteria);
+
+        searchCriteria = new SearchCriteria();
+        searchCriteria.setSearchCondition(SearchCondition.EQUAL);
+        searchCriteria.setValue(entityTypeId3);
+        searchCriteria.setSearchField(EntitySearchField.ENTITY_TYPE_ID);
+        filters.add(searchCriteria);
+
+        Assert.assertTrue(sharingRegistryServerHandler.searchEntities(domainId, userId1, filters, 0, -1).size() > 0);
+
+        Assert.assertNotNull(sharingRegistryServerHandler.getListOfSharedUsers(domainId, entityId1, permissionTypeId1));
+        Assert.assertNotNull(sharingRegistryServerHandler.getListOfSharedGroups(domainId, entityId1, permissionTypeId1));
+
+        Assert.assertTrue(sharingRegistryServerHandler.getListOfSharedUsers(domainId, entityId1, domainId + ":OWNER").size()==1);
+
+        // test changing parent - old INDIRECT_CASCADING permissions removed, new is added
+        // entityId2's parent is entityId1. entityId1 is shared with userId2
+        Assert.assertTrue(sharingRegistryServerHandler.userHasAccess(domainId, userId2, entityId1, permissionTypeId1));
+        Assert.assertTrue(sharingRegistryServerHandler.userHasAccess(domainId, userId2, entityId2, permissionTypeId1));
+        Assert.assertFalse(sharingRegistryServerHandler.userHasAccess(domainId, userId3, entityId2, permissionTypeId1));
+        // create a different parent entity
+        Entity entity6 = new Entity();
+        entity6.setEntityId(domainId+":Entity6");
+        entity6.setDomainId(domainId);
+        entity6.setEntityTypeId(entityTypeId1);
+        entity6.setOwnerId(userId1);
+        entity6.setName("Project name 2");
+        entity6.setDescription("Project description");
+        entity6.setFullText("Project name project description");
+        entity6.setCreatedTime(System.currentTimeMillis());
+        entity6.setUpdatedTime(System.currentTimeMillis());
+        String entityId6 = sharingRegistryServerHandler.createEntity(entity6);
+        Assert.assertNotNull(entityId6);
+
+        sharingRegistryServerHandler.shareEntityWithUsers(domainId, entityId6, Arrays.asList(userId3), permissionTypeId1, true);
+        Assert.assertTrue(sharingRegistryServerHandler.userHasAccess(domainId, userId3, entityId6, permissionTypeId1));
+        // Make sure entityId2 isn't shared with userId7 and then share it directly
+        Assert.assertFalse(sharingRegistryServerHandler.userHasAccess(domainId, userId7, entityId2, permissionTypeId1));
+        sharingRegistryServerHandler.shareEntityWithUsers(domainId, entityId2, Arrays.asList(userId7), permissionTypeId1, true);
+        Assert.assertTrue(sharingRegistryServerHandler.userHasAccess(domainId, userId7, entityId2, permissionTypeId1));
+        entity2.setParentEntityId(entityId6);
+        logger.debug("Updating entity2");
+        Assert.assertTrue(sharingRegistryServerHandler.updateEntity(entity2));
+        Entity entity2Updated = sharingRegistryServerHandler.getEntity(domainId, entityId2);
+        Assert.assertEquals(entityId6, entity2Updated.getParentEntityId());
+        // parent changed so entityId2 should now be shared with entityId6's shared users (userId3)
+        Assert.assertFalse(sharingRegistryServerHandler.userHasAccess(domainId, userId2, entityId2, permissionTypeId1));
+        Assert.assertTrue(sharingRegistryServerHandler.userHasAccess(domainId, userId3, entityId2, permissionTypeId1));
+        // entityId2 should still be shared with userId7 since that was directly shared
+        Assert.assertTrue(sharingRegistryServerHandler.userHasAccess(domainId, userId7, entityId2, permissionTypeId1));
+
+        Assert.assertEquals(Arrays.asList(user3), sharingRegistryServerHandler.getListOfDirectlySharedUsers(domainId, entityId6, permissionTypeId1));
+        Assert.assertEquals(Arrays.asList(user7), sharingRegistryServerHandler.getListOfDirectlySharedUsers(domainId, entityId2, permissionTypeId1));
+        List<User> entityId2SharedUsers = sharingRegistryServerHandler.getListOfSharedUsers(domainId, entityId2, permissionTypeId1);
+        Assert.assertEquals(2, entityId2SharedUsers.size());
+        Assert.assertTrue("user3 and user7 in shared users", entityId2SharedUsers.contains(user3) && entityId2SharedUsers.contains(user7));
+        Assert.assertEquals(1, sharingRegistryServerHandler.getListOfDirectlySharedGroups(domainId, entityId3, permissionTypeId1).size());
+        Assert.assertEquals(groupId2, sharingRegistryServerHandler.getListOfDirectlySharedGroups(domainId, entityId3, permissionTypeId1).get(0).getGroupId());
+    }
+}
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/test/java/org/apache/custos/sharing/registry/SharingRegistryServiceTest.java b/custos-sharing-registry-service/sharing-registry-server/src/test/java/org/apache/custos/sharing/registry/SharingRegistryServiceTest.java
new file mode 100644
index 0000000..c6777ff
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/test/java/org/apache/custos/sharing/registry/SharingRegistryServiceTest.java
@@ -0,0 +1,419 @@
+/**
+ *
+ * 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.custos.sharing.registry;
+
+import org.apache.custos.commons.exceptions.ApplicationSettingsException;
+import org.apache.custos.commons.utils.ServerSettings;
+import org.apache.custos.sharing.registry.models.*;
+import org.apache.custos.sharing.registry.server.SharingRegistryServer;
+import org.apache.custos.sharing.registry.service.cpi.SharingRegistryService;
+import org.apache.thrift.TException;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.protocol.TProtocol;
+import org.apache.thrift.transport.TSSLTransportFactory;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.transport.TTransport;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class SharingRegistryServiceTest {
+    private final static Logger logger = LoggerFactory.getLogger(SharingRegistryServiceTest.class);
+
+    @BeforeClass
+    public static void setUp() throws Exception {
+        SharingRegistryServer server = new SharingRegistryServer();
+        server.setTestMode(true);
+        server.start();
+        Thread.sleep(1000 * 2);
+    }
+
+
+    @Test
+    public void test() throws TException, InterruptedException, ApplicationSettingsException {
+        String serverHost = "localhost";
+        int serverPort = 7878;
+
+        SharingRegistryService.Client sharingServiceClient;
+        if (!ServerSettings.isSharingTLSEnabled()) {
+            TTransport transport = new TSocket(serverHost, serverPort);
+            transport.open();
+            TProtocol protocol = new TBinaryProtocol(transport);
+            sharingServiceClient = new SharingRegistryService.Client(protocol);
+        }else{
+            TSSLTransportFactory.TSSLTransportParameters params =
+                    new TSSLTransportFactory.TSSLTransportParameters();
+            params.setKeyStore(ServerSettings.getKeyStorePath(), ServerSettings.getKeyStorePassword());
+            params.setTrustStore(ServerSettings.getTrustStorePath(), ServerSettings.getTrustStorePassword());
+
+            TTransport transport = TSSLTransportFactory.getClientSocket(serverHost, serverPort, 10000, params);
+            TProtocol protocol = new TBinaryProtocol(transport);
+            sharingServiceClient = new SharingRegistryService.Client(protocol);
+        }
+
+        Domain domain = new Domain();
+        //has to be one word
+        domain.setName("test-domain" + Math.random());
+        //optional
+        domain.setDescription("test domain description");
+
+        String domainId = sharingServiceClient.createDomain(domain);
+        Assert.assertTrue(sharingServiceClient.isDomainExists(domainId));
+
+        User user1 = new User();
+        //required
+        user1.setUserId("test-user-1");
+        //required
+        user1.setUserName("test-user-1");
+        //required
+        user1.setDomainId(domainId);
+        //required
+        user1.setFirstName("John");
+        //required
+        user1.setLastName("Doe");
+        //required
+        user1.setEmail("john.doe@abc.com");
+        //optional - this should be bytes of the users image icon
+        //byte[] icon1 = new byte[10];
+        //user1.setIcon(icon1);
+
+        sharingServiceClient.createUser(user1);
+        Assert.assertTrue(sharingServiceClient.isUserExists(domainId, "test-user-1"));
+
+        User user2 = new User();
+        //required
+        user2.setUserId("test-user-2");
+        //required
+        user2.setUserName("test-user-2");
+        //required
+        user2.setDomainId(domainId);
+        //required
+        user2.setFirstName("John");
+        //required
+        user2.setLastName("Doe");
+        //required
+        user2.setEmail("john.doe@abc.com");
+        //optional - this should be bytes of the users image icon
+        //byte[] icon2 = new byte[10];
+        //user2.setIcon(icon2);
+
+        sharingServiceClient.createUser(user2);
+
+        User user3 = new User();
+        //required
+        user3.setUserId("test-user-3");
+        //required
+        user3.setUserName("test-user-3");
+        //required
+        user3.setDomainId(domainId);
+        //required
+        user3.setFirstName("John");
+        //required
+        user3.setLastName("Doe");
+        //required
+        user3.setEmail("john.doe@abc.com");
+        //optional - this should be bytes of the users image icon
+        //byte[] icon3 = new byte[10];
+        //user3.setIcon(icon3);
+
+        sharingServiceClient.createUser(user3);
+
+        User user7 = new User();
+        //required
+        user7.setUserId("test-user-7");
+        //required
+        user7.setUserName("test-user-7");
+        //required
+        user7.setDomainId(domainId);
+        //required
+        user7.setFirstName("John");
+        //required
+        user7.setLastName("Doe");
+        //required
+        user7.setEmail("john.doe@abc.com");
+        //optional - this should be bytes of the users image icon
+        //byte[] icon3 = new byte[10];
+        //user3.setIcon(icon3);
+
+        sharingServiceClient.createUser(user7);
+
+        // Test updates to user and how it affects the user's SINGLE_USER group
+        UserGroup singleUserGroupUser7 = sharingServiceClient.getGroup(domainId, user7.getUserId());
+        Assert.assertEquals(GroupCardinality.SINGLE_USER, singleUserGroupUser7.getGroupCardinality());
+        user7.setFirstName("Johnny");
+        sharingServiceClient.updatedUser(user7);
+        User updatedUser7 = sharingServiceClient.getUser(domainId, user7.getUserId());
+        Assert.assertEquals("Johnny", updatedUser7.getFirstName());
+        singleUserGroupUser7 = sharingServiceClient.getGroup(domainId, user7.getUserId());
+        Assert.assertEquals(GroupCardinality.SINGLE_USER, singleUserGroupUser7.getGroupCardinality());
+
+        UserGroup userGroup1 = new UserGroup();
+        //required
+        userGroup1.setGroupId("test-group-1");
+        //required
+        userGroup1.setDomainId(domainId);
+        //required
+        userGroup1.setName("test-group-1");
+        //optional
+        userGroup1.setDescription("test group description");
+        //required
+        userGroup1.setOwnerId("test-user-1");
+        //required
+        userGroup1.setGroupType(GroupType.USER_LEVEL_GROUP);
+
+        sharingServiceClient.createGroup(userGroup1);
+        userGroup1.setDescription("updated description");
+        sharingServiceClient.updateGroup(userGroup1);
+        Assert.assertTrue(sharingServiceClient.getGroup(domainId, userGroup1.getGroupId()).getDescription().equals("updated description"));
+        Assert.assertTrue(sharingServiceClient.isGroupExists(domainId, "test-group-1"));
+
+        UserGroup userGroup2 = new UserGroup();
+        //required
+        userGroup2.setGroupId("test-group-2");
+        //required
+        userGroup2.setDomainId(domainId);
+        //required
+        userGroup2.setName("test-group-2");
+        //optional
+        userGroup2.setDescription("test group description");
+        //required
+        userGroup2.setOwnerId("test-user-2");
+        //required
+        userGroup2.setGroupType(GroupType.USER_LEVEL_GROUP);
+
+        sharingServiceClient.createGroup(userGroup2);
+
+        sharingServiceClient.addUsersToGroup(domainId, Arrays.asList("test-user-3"), "test-group-2");
+
+        sharingServiceClient.addUsersToGroup(domainId, Arrays.asList("test-user-7"), "test-group-1");
+
+        sharingServiceClient.addChildGroupsToParentGroup(domainId, Arrays.asList("test-group-2"), "test-group-1");
+
+        //Group roles
+        Assert.assertTrue(sharingServiceClient.hasOwnerAccess(domainId, "test-group-1", "test-user-1"));
+
+        // user has admin access
+        Assert.assertTrue(sharingServiceClient.addGroupAdmins(domainId, "test-group-1", Arrays.asList("test-user-7")));
+        Assert.assertTrue(sharingServiceClient.hasAdminAccess(domainId, "test-group-1", "test-user-7"));
+
+        UserGroup getGroup = sharingServiceClient.getGroup(domainId, "test-group-1");
+        Assert.assertTrue(getGroup.getGroupAdmins().size() == 1);
+
+        Assert.assertTrue(sharingServiceClient.removeGroupAdmins(domainId, "test-group-1", Arrays.asList("test-user-7")));
+        Assert.assertFalse(sharingServiceClient.hasAdminAccess(domainId, "test-group-1", "test-user-7"));
+
+        // transfer group ownership
+        sharingServiceClient.addUsersToGroup(domainId, Arrays.asList("test-user-2"), "test-group-1");
+        Assert.assertTrue(sharingServiceClient.transferGroupOwnership(domainId, "test-group-1", "test-user-2"));
+        Assert.assertTrue(sharingServiceClient.hasOwnerAccess(domainId, "test-group-1", "test-user-2"));
+        Assert.assertTrue(sharingServiceClient.transferGroupOwnership(domainId, "test-group-1", "test-user-1"));
+        Assert.assertFalse(sharingServiceClient.hasOwnerAccess(domainId, "test-group-1", "test-user-2"));
+
+        PermissionType permissionType1 = new PermissionType();
+        //required
+        permissionType1.setPermissionTypeId("READ");
+        //required
+        permissionType1.setDomainId(domainId);
+        //required
+        permissionType1.setName("READ");
+        //optional
+        permissionType1.setDescription("READ description");
+        sharingServiceClient.createPermissionType(permissionType1);
+        Assert.assertTrue(sharingServiceClient.isPermissionExists(domainId, "READ"));
+
+        PermissionType permissionType2 = new PermissionType();
+        permissionType2.setPermissionTypeId("WRITE");
+        permissionType2.setDomainId(domainId);
+        permissionType2.setName("WRITE");
+        permissionType2.setDescription("WRITE description");
+        sharingServiceClient.createPermissionType(permissionType2);
+
+        PermissionType permissionType3 = new PermissionType();
+        permissionType3.setPermissionTypeId("CLONE");
+        permissionType3.setDomainId(domainId);
+        permissionType3.setName("CLONE");
+        permissionType3.setDescription("CLONE description");
+        sharingServiceClient.createPermissionType(permissionType3);
+
+        EntityType entityType1 = new EntityType();
+        //required
+        entityType1.setEntityTypeId("PROJECT");
+        //required
+        entityType1.setDomainId(domainId);
+        //required
+        entityType1.setName("PROJECT");
+        //optional
+        entityType1.setDescription("PROJECT entity type description");
+        sharingServiceClient.createEntityType(entityType1);
+        Assert.assertTrue(sharingServiceClient.isEntityTypeExists(domainId, "PROJECT"));
+
+        EntityType entityType2 = new EntityType();
+        entityType2.setEntityTypeId("EXPERIMENT");
+        entityType2.setDomainId(domainId);
+        entityType2.setName("EXPERIMENT");
+        entityType2.setDescription("EXPERIMENT entity type");
+        sharingServiceClient.createEntityType(entityType2);
+
+        EntityType entityType3 = new EntityType();
+        entityType3.setEntityTypeId("FILE");
+        entityType3.setDomainId(domainId);
+        entityType3.setName("FILE");
+        entityType3.setDescription("FILE entity type");
+        sharingServiceClient.createEntityType(entityType3);
+
+
+        //Creating entities
+        Entity entity1 = new Entity();
+        //required
+        entity1.setEntityId("test-project-1");
+        //required
+        entity1.setDomainId(domainId);
+        //required
+        entity1.setEntityTypeId("PROJECT");
+        //required
+        entity1.setOwnerId("test-user-1");
+        //required
+        entity1.setName("test-project-1");
+        //optional
+        entity1.setDescription("test project 1 description");
+        //optional
+        entity1.setFullText("test project 1 stampede gaussian seagrid");
+        //optional - If not set this will be default to current system time
+        entity1.setOriginalEntityCreationTime(System.currentTimeMillis());
+        sharingServiceClient.createEntity(entity1);
+        Assert.assertTrue(sharingServiceClient.isEntityExists(domainId, "test-project-1"));
+
+        Entity entity2 = new Entity();
+        entity2.setEntityId("test-experiment-1");
+        entity2.setDomainId(domainId);
+        entity2.setEntityTypeId("EXPERIMENT");
+        entity2.setOwnerId("test-user-1");
+        entity2.setName("test-experiment-1");
+        entity2.setDescription("test experiment 1 description");
+        entity2.setParentEntityId("test-project-1");
+        entity2.setFullText("test experiment 1 benzene");
+        sharingServiceClient.createEntity(entity2);
+
+
+        Entity entity3 = new Entity();
+        entity3.setEntityId("test-experiment-2");
+        entity3.setDomainId(domainId);
+        entity3.setEntityTypeId("EXPERIMENT");
+        entity3.setOwnerId("test-user-1");
+        entity3.setName("test-experiment-2");
+        entity3.setDescription("test experiment 2 description");
+        entity3.setParentEntityId("test-project-1");
+        entity3.setFullText("test experiment 1 3-methyl 1-butanol stampede");
+        sharingServiceClient.createEntity(entity3);
+
+
+        Entity entity4 = new Entity();
+        entity4.setEntityId("test-file-1");
+        entity4.setDomainId(domainId);
+        entity4.setEntityTypeId("FILE");
+        entity4.setOwnerId("test-user-1");
+        entity4.setName("test-file-1");
+        entity4.setDescription("test file 1 description");
+        entity4.setParentEntityId("test-experiment-2");
+        entity4.setFullText("test input file 1 for experiment 2");
+        sharingServiceClient.createEntity(entity4);
+
+        Assert.assertTrue(sharingServiceClient.getEntity(domainId, "test-project-1").getSharedCount() == 0);
+        sharingServiceClient.shareEntityWithUsers(domainId, "test-project-1", Arrays.asList("test-user-2"), "WRITE", true);
+        Assert.assertTrue(sharingServiceClient.getEntity(domainId, "test-project-1").getSharedCount() == 1);
+        ArrayList<SearchCriteria> filters = new ArrayList<>();
+        SearchCriteria searchCriteria = new SearchCriteria();
+        searchCriteria.setSearchField(EntitySearchField.SHARED_COUNT);
+        searchCriteria.setValue("1");
+        searchCriteria.setSearchCondition(SearchCondition.GTE);
+        filters.add(searchCriteria);
+        Assert.assertEquals(1, sharingServiceClient.searchEntities(domainId, "test-user-2", filters, 0, -1).size());
+
+
+        sharingServiceClient.revokeEntitySharingFromUsers(domainId, "test-project-1", Arrays.asList("test-user-2"), "WRITE");
+        Assert.assertTrue(sharingServiceClient.getEntity(domainId, "test-project-1").getSharedCount() == 0);
+        sharingServiceClient.shareEntityWithUsers(domainId, "test-project-1", Arrays.asList("test-user-2"), "WRITE", true);
+
+        sharingServiceClient.shareEntityWithGroups(domainId, "test-experiment-2", Arrays.asList("test-group-2"), "READ", true);
+        sharingServiceClient.shareEntityWithGroups(domainId, "test-experiment-2", Arrays.asList("test-group-2"), "CLONE", false);
+
+        //true
+        Assert.assertTrue(sharingServiceClient.userHasAccess(domainId, "test-user-2", "test-project-1", "WRITE"));
+        //true
+        Assert.assertTrue(sharingServiceClient.userHasAccess(domainId, "test-user-2", "test-experiment-1", "WRITE"));
+        //true
+        Assert.assertTrue(sharingServiceClient.userHasAccess(domainId, "test-user-2", "test-experiment-2", "WRITE"));
+
+        //false
+        Assert.assertFalse(sharingServiceClient.userHasAccess(domainId, "test-user-2", "test-experiment-1", "READ"));
+        //true
+        Assert.assertTrue(sharingServiceClient.userHasAccess(domainId, "test-user-2", "test-experiment-2", "READ"));
+
+        //false
+        Assert.assertFalse(sharingServiceClient.userHasAccess(domainId, "test-user-3", "test-project-1", "READ"));
+        //true
+        Assert.assertTrue(sharingServiceClient.userHasAccess(domainId, "test-user-3", "test-experiment-2", "READ"));
+        //false
+        Assert.assertFalse(sharingServiceClient.userHasAccess(domainId, "test-user-3", "test-experiment-2", "WRITE"));
+
+        //true
+        Assert.assertTrue((sharingServiceClient.userHasAccess(domainId, "test-user-3", "test-experiment-2", "CLONE")));
+        //false
+        Assert.assertFalse((sharingServiceClient.userHasAccess(domainId, "test-user-3", "test-file-1", "CLONE")));
+
+        filters = new ArrayList<>();
+        searchCriteria = new SearchCriteria();
+        searchCriteria.setSearchCondition(SearchCondition.FULL_TEXT);
+        searchCriteria.setValue("experiment");
+        searchCriteria.setSearchField(EntitySearchField.FULL_TEXT);
+        filters.add(searchCriteria);
+
+        searchCriteria = new SearchCriteria();
+        searchCriteria.setSearchCondition(SearchCondition.EQUAL);
+        searchCriteria.setValue("EXPERIMENT");
+        searchCriteria.setSearchField(EntitySearchField.ENTITY_TYPE_ID);
+        filters.add(searchCriteria);
+
+        searchCriteria = new SearchCriteria();
+        searchCriteria.setSearchCondition(SearchCondition.EQUAL);
+        searchCriteria.setValue("READ");
+        searchCriteria.setSearchField(EntitySearchField.PERMISSION_TYPE_ID);
+        filters.add(searchCriteria);
+
+        Assert.assertTrue(sharingServiceClient.searchEntities(domainId, "test-user-2", filters, 0, -1).size() == 1);
+        Entity persistedEntity = sharingServiceClient.searchEntities(
+                domainId, "test-user-2", filters, 0, -1).get(0);
+        Assert.assertEquals(entity3.getName(), persistedEntity.getName());
+        Assert.assertEquals(entity3.getDescription(), persistedEntity.getDescription());
+        Assert.assertEquals(entity3.getFullText(), persistedEntity.getFullText());
+
+        searchCriteria = new SearchCriteria();
+        searchCriteria.setSearchCondition(SearchCondition.NOT);
+        searchCriteria.setValue("test-user-1");
+        searchCriteria.setSearchField(EntitySearchField.OWNER_ID);
+        filters.add(searchCriteria);
+        Assert.assertTrue(sharingServiceClient.searchEntities(domainId, "test-user-2", filters, 0, -1).size() == 0);
+    }
+}
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/test/resources/airavata.jks b/custos-sharing-registry-service/sharing-registry-server/src/test/resources/airavata.jks
new file mode 100644
index 0000000..e0e46e2
Binary files /dev/null and b/custos-sharing-registry-service/sharing-registry-server/src/test/resources/airavata.jks differ
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/test/resources/client_truststore.jks b/custos-sharing-registry-service/sharing-registry-server/src/test/resources/client_truststore.jks
new file mode 100644
index 0000000..4ff588f
Binary files /dev/null and b/custos-sharing-registry-service/sharing-registry-server/src/test/resources/client_truststore.jks differ
diff --git a/custos-sharing-registry-service/sharing-registry-server/src/test/resources/logback.xml b/custos-sharing-registry-service/sharing-registry-server/src/test/resources/logback.xml
new file mode 100644
index 0000000..88937d3
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-server/src/test/resources/logback.xml
@@ -0,0 +1,31 @@
+<?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.
+  ~
+  -->
+<configuration>
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>[%p] %m%n</pattern>
+        </encoder>
+    </appender>
+    <!-- <logger name="org.apache.airavata.sharing.registry" level="DEBUG"/> -->
+    <root level="INFO">
+        <appender-ref ref="CONSOLE"/>
+    </root>
+</configuration>
diff --git a/custos-sharing-registry-service/sharing-registry-stubs/pom.xml b/custos-sharing-registry-service/sharing-registry-stubs/pom.xml
new file mode 100644
index 0000000..01364ad
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-stubs/pom.xml
@@ -0,0 +1,77 @@
+<?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">
+    <parent>
+        <artifactId>custos-sharing-registry-service</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <relativePath>../pom.xml</relativePath>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-sharing-registry-stubs</artifactId>
+    <packaging>jar</packaging>
+    <name>Sharing Registry Stubs</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.thrift</groupId>
+            <artifactId>libthrift</artifactId>
+            <version>${thrift.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.5.1</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+            <!--<plugin>-->
+                <!--<groupId>com.google.code.maven-replacer-plugin</groupId>-->
+                <!--<artifactId>replacer</artifactId>-->
+                <!--<version>${maven.replacer.plugin.version}</version>-->
+                <!--<executions>-->
+                    <!--<execution>-->
+                        <!--<phase>generate-sources</phase>-->
+                        <!--<goals>-->
+                            <!--<goal>replace</goal>-->
+                        <!--</goals>-->
+                    <!--</execution>-->
+                <!--</executions>-->
+                <!--<configuration>-->
+                    <!--<includes>-->
+                        <!--<include>${basedir}/src/main/java/org/apache/airavata/**/*.java</include>-->
+                    <!--</includes>-->
+                    <!--<token>, date = ".*"</token>-->
+                    <!--<value> </value>-->
+                <!--</configuration>-->
+            <!--</plugin>-->
+        </plugins>
+    </build>
+</project>
diff --git a/custos-sharing-registry-service/sharing-registry-stubs/src/main/java/org/apache/custos/sharing/registry/client/SharingRegistryServiceClientFactory.java b/custos-sharing-registry-service/sharing-registry-stubs/src/main/java/org/apache/custos/sharing/registry/client/SharingRegistryServiceClientFactory.java
new file mode 100644
index 0000000..dbcb49a
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-stubs/src/main/java/org/apache/custos/sharing/registry/client/SharingRegistryServiceClientFactory.java
@@ -0,0 +1,44 @@
+/**
+ *
+ * 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.custos.sharing.registry.client;
+
+import org.apache.custos.sharing.registry.models.SharingRegistryException;
+import org.apache.custos.sharing.registry.service.cpi.SharingRegistryService;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.transport.TTransportException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SharingRegistryServiceClientFactory {
+    private final static Logger logger = LoggerFactory.getLogger(SharingRegistryServiceClientFactory.class);
+
+    public static SharingRegistryService.Client createSharingRegistryClient(String serverHost, int serverPort) throws SharingRegistryException {
+        try {
+            TSocket e = new TSocket(serverHost, serverPort);
+            e.open();
+            TBinaryProtocol protocol = new TBinaryProtocol(e);
+            return new SharingRegistryService.Client(protocol);
+        } catch (TTransportException var4) {
+            logger.error("failed to create sharing registry client", var4);
+            throw new SharingRegistryException();
+        }
+    }
+}
\ No newline at end of file
diff --git a/custos-sharing-registry-service/sharing-registry-stubs/src/main/java/org/apache/custos/sharing/registry/models/Domain.java b/custos-sharing-registry-service/sharing-registry-stubs/src/main/java/org/apache/custos/sharing/registry/models/Domain.java
new file mode 100644
index 0000000..d61f613
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-stubs/src/main/java/org/apache/custos/sharing/registry/models/Domain.java
@@ -0,0 +1,805 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.custos.sharing.registry.models;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+/**
+ * <p>Domain is the entity that enables multi-tenency in this componenet. Every tenant will be
+ * operating separately it's own silo which is identified by the domain id. In the current implementation domain id
+ * will be same as the domain name</p>
+ * <li>domainId : Will be generated by the server based on the domain name</li>
+ * <li><b>name</b> : A single word name that identifies the domain e.g seagrid, ultrascan</li>
+ * <li>description : A short description for the domain</li>
+ * <li>createdTime : Will be set by the system</li>
+ * <li>updatedTime : Will be set by the system</li>
+ * 
+ */
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)", date = "2019-08-13")
+public class Domain implements org.apache.thrift.TBase<Domain, Domain._Fields>, java.io.Serializable, Cloneable, Comparable<Domain> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Domain");
+
+  private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
+  private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)2);
+  private static final org.apache.thrift.protocol.TField DESCRIPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("description", org.apache.thrift.protocol.TType.STRING, (short)3);
+  private static final org.apache.thrift.protocol.TField CREATED_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("createdTime", org.apache.thrift.protocol.TType.I64, (short)4);
+  private static final org.apache.thrift.protocol.TField UPDATED_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("updatedTime", org.apache.thrift.protocol.TType.I64, (short)5);
+
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new DomainStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new DomainTupleSchemeFactory();
+
+  public @org.apache.thrift.annotation.Nullable String domainId; // optional
+  public @org.apache.thrift.annotation.Nullable String name; // optional
+  public @org.apache.thrift.annotation.Nullable String description; // optional
+  public long createdTime; // optional
+  public long updatedTime; // optional
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    DOMAIN_ID((short)1, "domainId"),
+    NAME((short)2, "name"),
+    DESCRIPTION((short)3, "description"),
+    CREATED_TIME((short)4, "createdTime"),
+    UPDATED_TIME((short)5, "updatedTime");
+
+    private static final java.util.Map<String, _Fields> byName = new java.util.HashMap<String, _Fields>();
+
+    static {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // DOMAIN_ID
+          return DOMAIN_ID;
+        case 2: // NAME
+          return NAME;
+        case 3: // DESCRIPTION
+          return DESCRIPTION;
+        case 4: // CREATED_TIME
+          return CREATED_TIME;
+        case 5: // UPDATED_TIME
+          return UPDATED_TIME;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByName(String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final String _fieldName;
+
+    _Fields(short thriftId, String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  private static final int __CREATEDTIME_ISSET_ID = 0;
+  private static final int __UPDATEDTIME_ISSET_ID = 1;
+  private byte __isset_bitfield = 0;
+  private static final _Fields optionals[] = {_Fields.DOMAIN_ID,_Fields.NAME,_Fields.DESCRIPTION,_Fields.CREATED_TIME,_Fields.UPDATED_TIME};
+  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    tmpMap.put(_Fields.DESCRIPTION, new org.apache.thrift.meta_data.FieldMetaData("description", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    tmpMap.put(_Fields.CREATED_TIME, new org.apache.thrift.meta_data.FieldMetaData("createdTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
+    tmpMap.put(_Fields.UPDATED_TIME, new org.apache.thrift.meta_data.FieldMetaData("updatedTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Domain.class, metaDataMap);
+  }
+
+  public Domain() {
+    this.domainId = "DO_NOT_SET_AT_CLIENTS_ID";
+
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public Domain(Domain other) {
+    __isset_bitfield = other.__isset_bitfield;
+    if (other.isSetDomainId()) {
+      this.domainId = other.domainId;
+    }
+    if (other.isSetName()) {
+      this.name = other.name;
+    }
+    if (other.isSetDescription()) {
+      this.description = other.description;
+    }
+    this.createdTime = other.createdTime;
+    this.updatedTime = other.updatedTime;
+  }
+
+  public Domain deepCopy() {
+    return new Domain(this);
+  }
+
+  @Override
+  public void clear() {
+    this.domainId = "DO_NOT_SET_AT_CLIENTS_ID";
+
+    this.name = null;
+    this.description = null;
+    setCreatedTimeIsSet(false);
+    this.createdTime = 0;
+    setUpdatedTimeIsSet(false);
+    this.updatedTime = 0;
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public String getDomainId() {
+    return this.domainId;
+  }
+
+  public Domain setDomainId(@org.apache.thrift.annotation.Nullable String domainId) {
+    this.domainId = domainId;
+    return this;
+  }
+
+  public void unsetDomainId() {
+    this.domainId = null;
+  }
+
+  /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
+  public boolean isSetDomainId() {
+    return this.domainId != null;
+  }
+
+  public void setDomainIdIsSet(boolean value) {
+    if (!value) {
+      this.domainId = null;
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public String getName() {
+    return this.name;
+  }
+
+  public Domain setName(@org.apache.thrift.annotation.Nullable String name) {
+    this.name = name;
+    return this;
+  }
+
+  public void unsetName() {
+    this.name = null;
+  }
+
+  /** Returns true if field name is set (has been assigned a value) and false otherwise */
+  public boolean isSetName() {
+    return this.name != null;
+  }
+
+  public void setNameIsSet(boolean value) {
+    if (!value) {
+      this.name = null;
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public String getDescription() {
+    return this.description;
+  }
+
+  public Domain setDescription(@org.apache.thrift.annotation.Nullable String description) {
+    this.description = description;
+    return this;
+  }
+
+  public void unsetDescription() {
+    this.description = null;
+  }
+
+  /** Returns true if field description is set (has been assigned a value) and false otherwise */
+  public boolean isSetDescription() {
+    return this.description != null;
+  }
+
+  public void setDescriptionIsSet(boolean value) {
+    if (!value) {
+      this.description = null;
+    }
+  }
+
+  public long getCreatedTime() {
+    return this.createdTime;
+  }
+
+  public Domain setCreatedTime(long createdTime) {
+    this.createdTime = createdTime;
+    setCreatedTimeIsSet(true);
+    return this;
+  }
+
+  public void unsetCreatedTime() {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __CREATEDTIME_ISSET_ID);
+  }
+
+  /** Returns true if field createdTime is set (has been assigned a value) and false otherwise */
+  public boolean isSetCreatedTime() {
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __CREATEDTIME_ISSET_ID);
+  }
+
+  public void setCreatedTimeIsSet(boolean value) {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __CREATEDTIME_ISSET_ID, value);
+  }
+
+  public long getUpdatedTime() {
+    return this.updatedTime;
+  }
+
+  public Domain setUpdatedTime(long updatedTime) {
+    this.updatedTime = updatedTime;
+    setUpdatedTimeIsSet(true);
+    return this;
+  }
+
+  public void unsetUpdatedTime() {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __UPDATEDTIME_ISSET_ID);
+  }
+
+  /** Returns true if field updatedTime is set (has been assigned a value) and false otherwise */
+  public boolean isSetUpdatedTime() {
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __UPDATEDTIME_ISSET_ID);
+  }
+
+  public void setUpdatedTimeIsSet(boolean value) {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __UPDATEDTIME_ISSET_ID, value);
+  }
+
+  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable Object value) {
+    switch (field) {
+    case DOMAIN_ID:
+      if (value == null) {
+        unsetDomainId();
+      } else {
+        setDomainId((String)value);
+      }
+      break;
+
+    case NAME:
+      if (value == null) {
+        unsetName();
+      } else {
+        setName((String)value);
+      }
+      break;
+
+    case DESCRIPTION:
+      if (value == null) {
+        unsetDescription();
+      } else {
+        setDescription((String)value);
+      }
+      break;
+
+    case CREATED_TIME:
+      if (value == null) {
+        unsetCreatedTime();
+      } else {
+        setCreatedTime((Long)value);
+      }
+      break;
+
+    case UPDATED_TIME:
+      if (value == null) {
+        unsetUpdatedTime();
+      } else {
+        setUpdatedTime((Long)value);
+      }
+      break;
+
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public Object getFieldValue(_Fields field) {
+    switch (field) {
+    case DOMAIN_ID:
+      return getDomainId();
+
+    case NAME:
+      return getName();
+
+    case DESCRIPTION:
+      return getDescription();
+
+    case CREATED_TIME:
+      return getCreatedTime();
+
+    case UPDATED_TIME:
+      return getUpdatedTime();
+
+    }
+    throw new IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new IllegalArgumentException();
+    }
+
+    switch (field) {
+    case DOMAIN_ID:
+      return isSetDomainId();
+    case NAME:
+      return isSetName();
+    case DESCRIPTION:
+      return isSetDescription();
+    case CREATED_TIME:
+      return isSetCreatedTime();
+    case UPDATED_TIME:
+      return isSetUpdatedTime();
+    }
+    throw new IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof Domain)
+      return this.equals((Domain)that);
+    return false;
+  }
+
+  public boolean equals(Domain that) {
+    if (that == null)
+      return false;
+    if (this == that)
+      return true;
+
+    boolean this_present_domainId = true && this.isSetDomainId();
+    boolean that_present_domainId = true && that.isSetDomainId();
+    if (this_present_domainId || that_present_domainId) {
+      if (!(this_present_domainId && that_present_domainId))
+        return false;
+      if (!this.domainId.equals(that.domainId))
+        return false;
+    }
+
+    boolean this_present_name = true && this.isSetName();
+    boolean that_present_name = true && that.isSetName();
+    if (this_present_name || that_present_name) {
+      if (!(this_present_name && that_present_name))
+        return false;
+      if (!this.name.equals(that.name))
+        return false;
+    }
+
+    boolean this_present_description = true && this.isSetDescription();
+    boolean that_present_description = true && that.isSetDescription();
+    if (this_present_description || that_present_description) {
+      if (!(this_present_description && that_present_description))
+        return false;
+      if (!this.description.equals(that.description))
+        return false;
+    }
+
+    boolean this_present_createdTime = true && this.isSetCreatedTime();
+    boolean that_present_createdTime = true && that.isSetCreatedTime();
+    if (this_present_createdTime || that_present_createdTime) {
+      if (!(this_present_createdTime && that_present_createdTime))
+        return false;
+      if (this.createdTime != that.createdTime)
+        return false;
+    }
+
+    boolean this_present_updatedTime = true && this.isSetUpdatedTime();
+    boolean that_present_updatedTime = true && that.isSetUpdatedTime();
+    if (this_present_updatedTime || that_present_updatedTime) {
+      if (!(this_present_updatedTime && that_present_updatedTime))
+        return false;
+      if (this.updatedTime != that.updatedTime)
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int hashCode = 1;
+
+    hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
+    if (isSetDomainId())
+      hashCode = hashCode * 8191 + domainId.hashCode();
+
+    hashCode = hashCode * 8191 + ((isSetName()) ? 131071 : 524287);
+    if (isSetName())
+      hashCode = hashCode * 8191 + name.hashCode();
+
+    hashCode = hashCode * 8191 + ((isSetDescription()) ? 131071 : 524287);
+    if (isSetDescription())
+      hashCode = hashCode * 8191 + description.hashCode();
+
+    hashCode = hashCode * 8191 + ((isSetCreatedTime()) ? 131071 : 524287);
+    if (isSetCreatedTime())
+      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(createdTime);
+
+    hashCode = hashCode * 8191 + ((isSetUpdatedTime()) ? 131071 : 524287);
+    if (isSetUpdatedTime())
+      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(updatedTime);
+
+    return hashCode;
+  }
+
+  @Override
+  public int compareTo(Domain other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+
+    lastComparison = Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetDomainId()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetName()).compareTo(other.isSetName());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetName()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetDescription()).compareTo(other.isSetDescription());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetDescription()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.description, other.description);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetCreatedTime()).compareTo(other.isSetCreatedTime());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetCreatedTime()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.createdTime, other.createdTime);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetUpdatedTime()).compareTo(other.isSetUpdatedTime());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetUpdatedTime()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.updatedTime, other.updatedTime);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    scheme(iprot).read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    scheme(oprot).write(oprot, this);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("Domain(");
+    boolean first = true;
+
+    if (isSetDomainId()) {
+      sb.append("domainId:");
+      if (this.domainId == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.domainId);
+      }
+      first = false;
+    }
+    if (isSetName()) {
+      if (!first) sb.append(", ");
+      sb.append("name:");
+      if (this.name == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.name);
+      }
+      first = false;
+    }
+    if (isSetDescription()) {
+      if (!first) sb.append(", ");
+      sb.append("description:");
+      if (this.description == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.description);
+      }
+      first = false;
+    }
+    if (isSetCreatedTime()) {
+      if (!first) sb.append(", ");
+      sb.append("createdTime:");
+      sb.append(this.createdTime);
+      first = false;
+    }
+    if (isSetUpdatedTime()) {
+      if (!first) sb.append(", ");
+      sb.append("updatedTime:");
+      sb.append(this.updatedTime);
+      first = false;
+    }
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    try {
+      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+      __isset_bitfield = 0;
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class DomainStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public DomainStandardScheme getScheme() {
+      return new DomainStandardScheme();
+    }
+  }
+
+  private static class DomainStandardScheme extends org.apache.thrift.scheme.StandardScheme<Domain> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, Domain struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // DOMAIN_ID
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.domainId = iprot.readString();
+              struct.setDomainIdIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 2: // NAME
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.name = iprot.readString();
+              struct.setNameIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 3: // DESCRIPTION
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.description = iprot.readString();
+              struct.setDescriptionIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 4: // CREATED_TIME
+            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
+              struct.createdTime = iprot.readI64();
+              struct.setCreatedTimeIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 5: // UPDATED_TIME
+            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
+              struct.updatedTime = iprot.readI64();
+              struct.setUpdatedTimeIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, Domain struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      if (struct.domainId != null) {
+        if (struct.isSetDomainId()) {
+          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
+          oprot.writeString(struct.domainId);
+          oprot.writeFieldEnd();
+        }
+      }
+      if (struct.name != null) {
+        if (struct.isSetName()) {
+          oprot.writeFieldBegin(NAME_FIELD_DESC);
+          oprot.writeString(struct.name);
+          oprot.writeFieldEnd();
+        }
+      }
+      if (struct.description != null) {
+        if (struct.isSetDescription()) {
+          oprot.writeFieldBegin(DESCRIPTION_FIELD_DESC);
+          oprot.writeString(struct.description);
+          oprot.writeFieldEnd();
+        }
+      }
+      if (struct.isSetCreatedTime()) {
+        oprot.writeFieldBegin(CREATED_TIME_FIELD_DESC);
+        oprot.writeI64(struct.createdTime);
+        oprot.writeFieldEnd();
+      }
+      if (struct.isSetUpdatedTime()) {
+        oprot.writeFieldBegin(UPDATED_TIME_FIELD_DESC);
+        oprot.writeI64(struct.updatedTime);
+        oprot.writeFieldEnd();
+      }
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class DomainTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public DomainTupleScheme getScheme() {
+      return new DomainTupleScheme();
+    }
+  }
+
+  private static class DomainTupleScheme extends org.apache.thrift.scheme.TupleScheme<Domain> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, Domain struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
+      if (struct.isSetDomainId()) {
+        optionals.set(0);
+      }
+      if (struct.isSetName()) {
+        optionals.set(1);
+      }
+      if (struct.isSetDescription()) {
+        optionals.set(2);
+      }
+      if (struct.isSetCreatedTime()) {
+        optionals.set(3);
+      }
+      if (struct.isSetUpdatedTime()) {
+        optionals.set(4);
+      }
+      oprot.writeBitSet(optionals, 5);
+      if (struct.isSetDomainId()) {
+        oprot.writeString(struct.domainId);
+      }
+      if (struct.isSetName()) {
+        oprot.writeString(struct.name);
+      }
+      if (struct.isSetDescription()) {
+        oprot.writeString(struct.description);
+      }
+      if (struct.isSetCreatedTime()) {
+        oprot.writeI64(struct.createdTime);
+      }
+      if (struct.isSetUpdatedTime()) {
+        oprot.writeI64(struct.updatedTime);
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, Domain struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(5);
+      if (incoming.get(0)) {
+        struct.domainId = iprot.readString();
+        struct.setDomainIdIsSet(true);
+      }
+      if (incoming.get(1)) {
+        struct.name = iprot.readString();
+        struct.setNameIsSet(true);
+      }
+      if (incoming.get(2)) {
+        struct.description = iprot.readString();
+        struct.setDescriptionIsSet(true);
+      }
+      if (incoming.get(3)) {
+        struct.createdTime = iprot.readI64();
+        struct.setCreatedTimeIsSet(true);
+      }
+      if (incoming.get(4)) {
+        struct.updatedTime = iprot.readI64();
+        struct.setUpdatedTimeIsSet(true);
+      }
+    }
+  }
+
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+}
+
diff --git a/custos-sharing-registry-service/sharing-registry-stubs/src/main/java/org/apache/custos/sharing/registry/models/DuplicateEntryException.java b/custos-sharing-registry-service/sharing-registry-stubs/src/main/java/org/apache/custos/sharing/registry/models/DuplicateEntryException.java
new file mode 100644
index 0000000..bcbf29a
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-stubs/src/main/java/org/apache/custos/sharing/registry/models/DuplicateEntryException.java
@@ -0,0 +1,377 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.custos.sharing.registry.models;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+/**
+ * This exception is thrown when you try to save a duplicate entity that already exists
+ *   in the database.
+ * 
+ *   message: contains the associated error message
+ * 
+ */
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)", date = "2019-08-13")
+public class DuplicateEntryException extends org.apache.thrift.TException implements org.apache.thrift.TBase<DuplicateEntryException, DuplicateEntryException._Fields>, java.io.Serializable, Cloneable, Comparable<DuplicateEntryException> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("DuplicateEntryException");
+
+  private static final org.apache.thrift.protocol.TField MESSAGE_FIELD_DESC = new org.apache.thrift.protocol.TField("message", org.apache.thrift.protocol.TType.STRING, (short)1);
+
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new DuplicateEntryExceptionStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new DuplicateEntryExceptionTupleSchemeFactory();
+
+  public @org.apache.thrift.annotation.Nullable String message; // required
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    MESSAGE((short)1, "message");
+
+    private static final java.util.Map<String, _Fields> byName = new java.util.HashMap<String, _Fields>();
+
+    static {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // MESSAGE
+          return MESSAGE;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByName(String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final String _fieldName;
+
+    _Fields(short thriftId, String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.MESSAGE, new org.apache.thrift.meta_data.FieldMetaData("message", org.apache.thrift.TFieldRequirementType.REQUIRED, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(DuplicateEntryException.class, metaDataMap);
+  }
+
+  public DuplicateEntryException() {
+  }
+
+  public DuplicateEntryException(
+    String message)
+  {
+    this();
+    this.message = message;
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public DuplicateEntryException(DuplicateEntryException other) {
+    if (other.isSetMessage()) {
+      this.message = other.message;
+    }
+  }
+
+  public DuplicateEntryException deepCopy() {
+    return new DuplicateEntryException(this);
+  }
+
+  @Override
+  public void clear() {
+    this.message = null;
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public String getMessage() {
+    return this.message;
+  }
+
+  public DuplicateEntryException setMessage(@org.apache.thrift.annotation.Nullable String message) {
+    this.message = message;
+    return this;
+  }
+
+  public void unsetMessage() {
+    this.message = null;
+  }
+
+  /** Returns true if field message is set (has been assigned a value) and false otherwise */
+  public boolean isSetMessage() {
+    return this.message != null;
+  }
+
+  public void setMessageIsSet(boolean value) {
+    if (!value) {
+      this.message = null;
+    }
+  }
+
+  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable Object value) {
+    switch (field) {
+    case MESSAGE:
+      if (value == null) {
+        unsetMessage();
+      } else {
+        setMessage((String)value);
+      }
+      break;
+
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public Object getFieldValue(_Fields field) {
+    switch (field) {
+    case MESSAGE:
+      return getMessage();
+
+    }
+    throw new IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new IllegalArgumentException();
+    }
+
+    switch (field) {
+    case MESSAGE:
+      return isSetMessage();
+    }
+    throw new IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof DuplicateEntryException)
+      return this.equals((DuplicateEntryException)that);
+    return false;
+  }
+
+  public boolean equals(DuplicateEntryException that) {
+    if (that == null)
+      return false;
+    if (this == that)
+      return true;
+
+    boolean this_present_message = true && this.isSetMessage();
+    boolean that_present_message = true && that.isSetMessage();
+    if (this_present_message || that_present_message) {
+      if (!(this_present_message && that_present_message))
+        return false;
+      if (!this.message.equals(that.message))
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int hashCode = 1;
+
+    hashCode = hashCode * 8191 + ((isSetMessage()) ? 131071 : 524287);
+    if (isSetMessage())
+      hashCode = hashCode * 8191 + message.hashCode();
+
+    return hashCode;
+  }
+
+  @Override
+  public int compareTo(DuplicateEntryException other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+
+    lastComparison = Boolean.valueOf(isSetMessage()).compareTo(other.isSetMessage());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetMessage()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.message, other.message);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    scheme(iprot).read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    scheme(oprot).write(oprot, this);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("DuplicateEntryException(");
+    boolean first = true;
+
+    sb.append("message:");
+    if (this.message == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.message);
+    }
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    if (message == null) {
+      throw new org.apache.thrift.protocol.TProtocolException("Required field 'message' was not present! Struct: " + toString());
+    }
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    try {
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class DuplicateEntryExceptionStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public DuplicateEntryExceptionStandardScheme getScheme() {
+      return new DuplicateEntryExceptionStandardScheme();
+    }
+  }
+
+  private static class DuplicateEntryExceptionStandardScheme extends org.apache.thrift.scheme.StandardScheme<DuplicateEntryException> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, DuplicateEntryException struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // MESSAGE
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.message = iprot.readString();
+              struct.setMessageIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, DuplicateEntryException struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      if (struct.message != null) {
+        oprot.writeFieldBegin(MESSAGE_FIELD_DESC);
+        oprot.writeString(struct.message);
+        oprot.writeFieldEnd();
+      }
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class DuplicateEntryExceptionTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public DuplicateEntryExceptionTupleScheme getScheme() {
+      return new DuplicateEntryExceptionTupleScheme();
+    }
+  }
+
+  private static class DuplicateEntryExceptionTupleScheme extends org.apache.thrift.scheme.TupleScheme<DuplicateEntryException> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, DuplicateEntryException struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      oprot.writeString(struct.message);
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, DuplicateEntryException struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      struct.message = iprot.readString();
+      struct.setMessageIsSet(true);
+    }
+  }
+
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+}
+
diff --git a/custos-sharing-registry-service/sharing-registry-stubs/src/main/java/org/apache/custos/sharing/registry/models/Entity.java b/custos-sharing-registry-service/sharing-registry-stubs/src/main/java/org/apache/custos/sharing/registry/models/Entity.java
new file mode 100644
index 0000000..613ea5d
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-registry-stubs/src/main/java/org/apache/custos/sharing/registry/models/Entity.java
@@ -0,0 +1,1663 @@
+/**
+ * Autogenerated by Thrift Compiler (0.12.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.custos.sharing.registry.models;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+/**
+ * <p>Entity object which is used to register an entity in the system.</p>
+ * <li><b>entityId</b> : Entity id provided by the client</li>
+ * <li><b>domainId</b> : Domain id</li>
+ * <li><b>entityTypeId</b> : Entity type id</li>
+ * <li><b>ownerId</b> : Owner id</li>
+ * <li>parentEntityId : Parent entity id</li>
+ * <li><b>name</b> : Name</li>
+ * <li>description : Short description for the entity</li>
+ * <li>binaryData : Any information stored in binary format</li>
+ * <li>fullText : A string which will be considered for full text search</li>
+ * <li><b>originalEntityCreationTime</b> : When registering old records what is the original entity creation time. If not
+ * set will be default to current time</li>
+ * <li>createdTime : Will be set by the system</li>
+ * <li>updatedTime : Will be set by the system</li>
+ * 
+ */
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.12.0)", date = "2019-08-13")
+public class Entity implements org.apache.thrift.TBase<Entity, Entity._Fields>, java.io.Serializable, Cloneable, Comparable<Entity> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Entity");
+
+  private static final org.apache.thrift.protocol.TField ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityId", org.apache.thrift.protocol.TType.STRING, (short)1);
+  private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)2);
+  private static final org.apache.thrift.protocol.TField ENTITY_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityTypeId", org.apache.thrift.protocol.TType.STRING, (short)3);
+  private static final org.apache.thrift.protocol.TField OWNER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("ownerId", org.apache.thrift.protocol.TType.STRING, (short)4);
+  private static final org.apache.thrift.protocol.TField PARENT_ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("parentEntityId", org.apache.thrift.protocol.TType.STRING, (short)5);
+  private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)6);
+  private static final org.apache.thrift.protocol.TField DESCRIPTION_FIELD_DESC = new org.apache.thrift.protocol.TField("description", org.apache.thrift.protocol.TType.STRING, (short)7);
+  private static final org.apache.thrift.protocol.TField BINARY_DATA_FIELD_DESC = new org.apache.thrift.protocol.TField("binaryData", org.apache.thrift.protocol.TType.STRING, (short)8);
+  private static final org.apache.thrift.protocol.TField FULL_TEXT_FIELD_DESC = new org.apache.thrift.protocol.TField("fullText", org.apache.thrift.protocol.TType.STRING, (short)9);
+  private static final org.apache.thrift.protocol.TField SHARED_COUNT_FIELD_DESC = new org.apache.thrift.protocol.TField("sharedCount", org.apache.thrift.protocol.TType.I64, (short)10);
+  private static final org.apache.thrift.protocol.TField ORIGINAL_ENTITY_CREATION_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("originalEntityCreationTime", org.apache.thrift.protocol.TType.I64, (short)11);
+  private static final org.apache.thrift.protocol.TField CREATED_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("createdTime", org.apache.thrift.protocol.TType.I64, (short)12);
+  private static final org.apache.thrift.protocol.TField UPDATED_TIME_FIELD_DESC = new org.apache.thrift.protocol.TField("updatedTime", org.apache.thrift.protocol.TType.I64, (short)13);
+
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new EntityStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new EntityTupleSchemeFactory();
+
+  public @org.apache.thrift.annotation.Nullable String entityId; // optional
+  public @org.apache.thrift.annotation.Nullable String domainId; // optional
+  public @org.apache.thrift.annotation.Nullable String entityTypeId; // optional
+  public @org.apache.thrift.annotation.Nullable String ownerId; // optional
+  public @org.apache.thrift.annotation.Nullable String parentEntityId; // optional
+  public @org.apache.thrift.annotation.Nullable String name; // optional
+  public @org.apache.thrift.annotation.Nullable String description; // optional
+  public @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer binaryData; // optional
+  public @org.apache.thrift.annotation.Nullable String fullText; // optional
+  public long sharedCount; // optional
+  public long originalEntityCreationTime; // optional
+  public long createdTime; // optional
+  public long updatedTime; // optional
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    ENTITY_ID((short)1, "entityId"),
+    DOMAIN_ID((short)2, "domainId"),
+    ENTITY_TYPE_ID((short)3, "entityTypeId"),
+    OWNER_ID((short)4, "ownerId"),
+    PARENT_ENTITY_ID((short)5, "parentEntityId"),
+    NAME((short)6, "name"),
+    DESCRIPTION((short)7, "description"),
+    BINARY_DATA((short)8, "binaryData"),
+    FULL_TEXT((short)9, "fullText"),
+    SHARED_COUNT((short)10, "sharedCount"),
+    ORIGINAL_ENTITY_CREATION_TIME((short)11, "originalEntityCreationTime"),
+    CREATED_TIME((short)12, "createdTime"),
+    UPDATED_TIME((short)13, "updatedTime");
+
+    private static final java.util.Map<String, _Fields> byName = new java.util.HashMap<String, _Fields>();
+
+    static {
+      for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // ENTITY_ID
+          return ENTITY_ID;
+        case 2: // DOMAIN_ID
+          return DOMAIN_ID;
+        case 3: // ENTITY_TYPE_ID
+          return ENTITY_TYPE_ID;
+        case 4: // OWNER_ID
+          return OWNER_ID;
+        case 5: // PARENT_ENTITY_ID
+          return PARENT_ENTITY_ID;
+        case 6: // NAME
+          return NAME;
+        case 7: // DESCRIPTION
+          return DESCRIPTION;
+        case 8: // BINARY_DATA
+          return BINARY_DATA;
+        case 9: // FULL_TEXT
+          return FULL_TEXT;
+        case 10: // SHARED_COUNT
+          return SHARED_COUNT;
+        case 11: // ORIGINAL_ENTITY_CREATION_TIME
+          return ORIGINAL_ENTITY_CREATION_TIME;
+        case 12: // CREATED_TIME
+          return CREATED_TIME;
+        case 13: // UPDATED_TIME
+          return UPDATED_TIME;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    @org.apache.thrift.annotation.Nullable
+    public static _Fields findByName(String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final String _fieldName;
+
+    _Fields(short thriftId, String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  private static final int __SHAREDCOUNT_ISSET_ID = 0;
+  private static final int __ORIGINALENTITYCREATIONTIME_ISSET_ID = 1;
+  private static final int __CREATEDTIME_ISSET_ID = 2;
+  private static final int __UPDATEDTIME_ISSET_ID = 3;
+  private byte __isset_bitfield = 0;
+  private static final _Fields optionals[] = {_Fields.ENTITY_ID,_Fields.DOMAIN_ID,_Fields.ENTITY_TYPE_ID,_Fields.OWNER_ID,_Fields.PARENT_ENTITY_ID,_Fields.NAME,_Fields.DESCRIPTION,_Fields.BINARY_DATA,_Fields.FULL_TEXT,_Fields.SHARED_COUNT,_Fields.ORIGINAL_ENTITY_CREATION_TIME,_Fields.CREATED_TIME,_Fields.UPDATED_TIME};
+  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("entityId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    tmpMap.put(_Fields.ENTITY_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("entityTypeId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    tmpMap.put(_Fields.OWNER_ID, new org.apache.thrift.meta_data.FieldMetaData("ownerId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    tmpMap.put(_Fields.PARENT_ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("parentEntityId", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    tmpMap.put(_Fields.DESCRIPTION, new org.apache.thrift.meta_data.FieldMetaData("description", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    tmpMap.put(_Fields.BINARY_DATA, new org.apache.thrift.meta_data.FieldMetaData("binaryData", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
+    tmpMap.put(_Fields.FULL_TEXT, new org.apache.thrift.meta_data.FieldMetaData("fullText", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    tmpMap.put(_Fields.SHARED_COUNT, new org.apache.thrift.meta_data.FieldMetaData("sharedCount", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
+    tmpMap.put(_Fields.ORIGINAL_ENTITY_CREATION_TIME, new org.apache.thrift.meta_data.FieldMetaData("originalEntityCreationTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
+    tmpMap.put(_Fields.CREATED_TIME, new org.apache.thrift.meta_data.FieldMetaData("createdTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
+    tmpMap.put(_Fields.UPDATED_TIME, new org.apache.thrift.meta_data.FieldMetaData("updatedTime", org.apache.thrift.TFieldRequirementType.OPTIONAL, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Entity.class, metaDataMap);
+  }
+
+  public Entity() {
+    this.sharedCount = 0L;
+
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public Entity(Entity other) {
+    __isset_bitfield = other.__isset_bitfield;
+    if (other.isSetEntityId()) {
+      this.entityId = other.entityId;
+    }
+    if (other.isSetDomainId()) {
+      this.domainId = other.domainId;
+    }
+    if (other.isSetEntityTypeId()) {
+      this.entityTypeId = other.entityTypeId;
+    }
+    if (other.isSetOwnerId()) {
+      this.ownerId = other.ownerId;
+    }
+    if (other.isSetParentEntityId()) {
+      this.parentEntityId = other.parentEntityId;
+    }
+    if (other.isSetName()) {
+      this.name = other.name;
+    }
+    if (other.isSetDescription()) {
+      this.description = other.description;
+    }
+    if (other.isSetBinaryData()) {
+      this.binaryData = org.apache.thrift.TBaseHelper.copyBinary(other.binaryData);
+    }
+    if (other.isSetFullText()) {
+      this.fullText = other.fullText;
+    }
+    this.sharedCount = other.sharedCount;
+    this.originalEntityCreationTime = other.originalEntityCreationTime;
+    this.createdTime = other.createdTime;
+    this.updatedTime = other.updatedTime;
+  }
+
+  public Entity deepCopy() {
+    return new Entity(this);
+  }
+
+  @Override
+  public void clear() {
+    this.entityId = null;
+    this.domainId = null;
+    this.entityTypeId = null;
+    this.ownerId = null;
+    this.parentEntityId = null;
+    this.name = null;
+    this.description = null;
+    this.binaryData = null;
+    this.fullText = null;
+    this.sharedCount = 0L;
+
+    setOriginalEntityCreationTimeIsSet(false);
+    this.originalEntityCreationTime = 0;
+    setCreatedTimeIsSet(false);
+    this.createdTime = 0;
+    setUpdatedTimeIsSet(false);
+    this.updatedTime = 0;
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public String getEntityId() {
+    return this.entityId;
+  }
+
+  public Entity setEntityId(@org.apache.thrift.annotation.Nullable String entityId) {
+    this.entityId = entityId;
+    return this;
+  }
+
+  public void unsetEntityId() {
+    this.entityId = null;
+  }
+
+  /** Returns true if field entityId is set (has been assigned a value) and false otherwise */
+  public boolean isSetEntityId() {
+    return this.entityId != null;
+  }
+
+  public void setEntityIdIsSet(boolean value) {
+    if (!value) {
+      this.entityId = null;
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public String getDomainId() {
+    return this.domainId;
+  }
+
+  public Entity setDomainId(@org.apache.thrift.annotation.Nullable String domainId) {
+    this.domainId = domainId;
+    return this;
+  }
+
+  public void unsetDomainId() {
+    this.domainId = null;
+  }
+
+  /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
+  public boolean isSetDomainId() {
+    return this.domainId != null;
+  }
+
+  public void setDomainIdIsSet(boolean value) {
+    if (!value) {
+      this.domainId = null;
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public String getEntityTypeId() {
+    return this.entityTypeId;
+  }
+
+  public Entity setEntityTypeId(@org.apache.thrift.annotation.Nullable String entityTypeId) {
+    this.entityTypeId = entityTypeId;
+    return this;
+  }
+
+  public void unsetEntityTypeId() {
+    this.entityTypeId = null;
+  }
+
+  /** Returns true if field entityTypeId is set (has been assigned a value) and false otherwise */
+  public boolean isSetEntityTypeId() {
+    return this.entityTypeId != null;
+  }
+
+  public void setEntityTypeIdIsSet(boolean value) {
+    if (!value) {
+      this.entityTypeId = null;
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public String getOwnerId() {
+    return this.ownerId;
+  }
+
+  public Entity setOwnerId(@org.apache.thrift.annotation.Nullable String ownerId) {
+    this.ownerId = ownerId;
+    return this;
+  }
+
+  public void unsetOwnerId() {
+    this.ownerId = null;
+  }
+
+  /** Returns true if field ownerId is set (has been assigned a value) and false otherwise */
+  public boolean isSetOwnerId() {
+    return this.ownerId != null;
+  }
+
+  public void setOwnerIdIsSet(boolean value) {
+    if (!value) {
+      this.ownerId = null;
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public String getParentEntityId() {
+    return this.parentEntityId;
+  }
+
+  public Entity setParentEntityId(@org.apache.thrift.annotation.Nullable String parentEntityId) {
+    this.parentEntityId = parentEntityId;
+    return this;
+  }
+
+  public void unsetParentEntityId() {
+    this.parentEntityId = null;
+  }
+
+  /** Returns true if field parentEntityId is set (has been assigned a value) and false otherwise */
+  public boolean isSetParentEntityId() {
+    return this.parentEntityId != null;
+  }
+
+  public void setParentEntityIdIsSet(boolean value) {
+    if (!value) {
+      this.parentEntityId = null;
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public String getName() {
+    return this.name;
+  }
+
+  public Entity setName(@org.apache.thrift.annotation.Nullable String name) {
+    this.name = name;
+    return this;
+  }
+
+  public void unsetName() {
+    this.name = null;
+  }
+
+  /** Returns true if field name is set (has been assigned a value) and false otherwise */
+  public boolean isSetName() {
+    return this.name != null;
+  }
+
+  public void setNameIsSet(boolean value) {
+    if (!value) {
+      this.name = null;
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public String getDescription() {
+    return this.description;
+  }
+
+  public Entity setDescription(@org.apache.thrift.annotation.Nullable String description) {
+    this.description = description;
+    return this;
+  }
+
+  public void unsetDescription() {
+    this.description = null;
+  }
+
+  /** Returns true if field description is set (has been assigned a value) and false otherwise */
+  public boolean isSetDescription() {
+    return this.description != null;
+  }
+
+  public void setDescriptionIsSet(boolean value) {
+    if (!value) {
+      this.description = null;
+    }
+  }
+
+  public byte[] getBinaryData() {
+    setBinaryData(org.apache.thrift.TBaseHelper.rightSize(binaryData));
+    return binaryData == null ? null : binaryData.array();
+  }
+
+  public java.nio.ByteBuffer bufferForBinaryData() {
+    return org.apache.thrift.TBaseHelper.copyBinary(binaryData);
+  }
+
+  public Entity setBinaryData(byte[] binaryData) {
+    this.binaryData = binaryData == null ? (java.nio.ByteBuffer)null   : java.nio.ByteBuffer.wrap(binaryData.clone());
+    return this;
+  }
+
+  public Entity setBinaryData(@org.apache.thrift.annotation.Nullable java.nio.ByteBuffer binaryData) {
+    this.binaryData = org.apache.thrift.TBaseHelper.copyBinary(binaryData);
+    return this;
+  }
+
+  public void unsetBinaryData() {
+    this.binaryData = null;
+  }
+
+  /** Returns true if field binaryData is set (has been assigned a value) and false otherwise */
+  public boolean isSetBinaryData() {
+    return this.binaryData != null;
+  }
+
+  public void setBinaryDataIsSet(boolean value) {
+    if (!value) {
+      this.binaryData = null;
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public String getFullText() {
+    return this.fullText;
+  }
+
+  public Entity setFullText(@org.apache.thrift.annotation.Nullable String fullText) {
+    this.fullText = fullText;
+    return this;
+  }
+
+  public void unsetFullText() {
+    this.fullText = null;
+  }
+
+  /** Returns true if field fullText is set (has been assigned a value) and false otherwise */
+  public boolean isSetFullText() {
+    return this.fullText != null;
+  }
+
+  public void setFullTextIsSet(boolean value) {
+    if (!value) {
+      this.fullText = null;
+    }
+  }
+
+  public long getSharedCount() {
+    return this.sharedCount;
+  }
+
+  public Entity setSharedCount(long sharedCount) {
+    this.sharedCount = sharedCount;
+    setSharedCountIsSet(true);
+    return this;
+  }
+
+  public void unsetSharedCount() {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SHAREDCOUNT_ISSET_ID);
+  }
+
+  /** Returns true if field sharedCount is set (has been assigned a value) and false otherwise */
+  public boolean isSetSharedCount() {
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SHAREDCOUNT_ISSET_ID);
+  }
+
+  public void setSharedCountIsSet(boolean value) {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SHAREDCOUNT_ISSET_ID, value);
+  }
+
+  public long getOriginalEntityCreationTime() {
+    return this.originalEntityCreationTime;
+  }
+
+  public Entity setOriginalEntityCreationTime(long originalEntityCreationTime) {
+    this.originalEntityCreationTime = originalEntityCreationTime;
+    setOriginalEntityCreationTimeIsSet(true);
+    return this;
+  }
+
+  public void unsetOriginalEntityCreationTime() {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __ORIGINALENTITYCREATIONTIME_ISSET_ID);
+  }
+
+  /** Returns true if field originalEntityCreationTime is set (has been assigned a value) and false otherwise */
+  public boolean isSetOriginalEntityCreationTime() {
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __ORIGINALENTITYCREATIONTIME_ISSET_ID);
+  }
+
+  public void setOriginalEntityCreationTimeIsSet(boolean value) {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __ORIGINALENTITYCREATIONTIME_ISSET_ID, value);
+  }
+
+  public long getCreatedTime() {
+    return this.createdTime;
+  }
+
+  public Entity setCreatedTime(long createdTime) {
+    this.createdTime = createdTime;
+    setCreatedTimeIsSet(true);
+    return this;
+  }
+
+  public void unsetCreatedTime() {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __CREATEDTIME_ISSET_ID);
+  }
+
+  /** Returns true if field createdTime is set (has been assigned a value) and false otherwise */
+  public boolean isSetCreatedTime() {
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __CREATEDTIME_ISSET_ID);
+  }
+
+  public void setCreatedTimeIsSet(boolean value) {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __CREATEDTIME_ISSET_ID, value);
+  }
+
+  public long getUpdatedTime() {
+    return this.updatedTime;
+  }
+
+  public Entity setUpdatedTime(long updatedTime) {
+    this.updatedTime = updatedTime;
+    setUpdatedTimeIsSet(true);
+    return this;
+  }
+
+  public void unsetUpdatedTime() {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __UPDATEDTIME_ISSET_ID);
+  }
+
+  /** Returns true if field updatedTime is set (has been assigned a value) and false otherwise */
+  public boolean isSetUpdatedTime() {
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __UPDATEDTIME_ISSET_ID);
+  }
+
+  public void setUpdatedTimeIsSet(boolean value) {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __UPDATEDTIME_ISSET_ID, value);
+  }
+
+  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable Object value) {
+    switch (field) {
+    case ENTITY_ID:
+      if (value == null) {
+        unsetEntityId();
+      } else {
+        setEntityId((String)value);
+      }
+      break;
+
+    case DOMAIN_ID:
+      if (value == null) {
+        unsetDomainId();
+      } else {
+        setDomainId((String)value);
+      }
+      break;
+
+    case ENTITY_TYPE_ID:
+      if (value == null) {
+        unsetEntityTypeId();
+      } else {
+        setEntityTypeId((String)value);
+      }
+      break;
+
+    case OWNER_ID:
+      if (value == null) {
+        unsetOwnerId();
+      } else {
+        setOwnerId((String)value);
+      }
+      break;
+
+    case PARENT_ENTITY_ID:
+      if (value == null) {
+        unsetParentEntityId();
+      } else {
+        setParentEntityId((String)value);
+      }
+      break;
+
+    case NAME:
+      if (value == null) {
+        unsetName();
+      } else {
+        setName((String)value);
+      }
+      break;
+
+    case DESCRIPTION:
+      if (value == null) {
+        unsetDescription();
+      } else {
+        setDescription((String)value);
+      }
+      break;
+
+    case BINARY_DATA:
+      if (value == null) {
+        unsetBinaryData();
+      } else {
+        if (value instanceof byte[]) {
+          setBinaryData((byte[])value);
+        } else {
+          setBinaryData((java.nio.ByteBuffer)value);
+        }
+      }
+      break;
+
+    case FULL_TEXT:
+      if (value == null) {
+        unsetFullText();
+      } else {
+        setFullText((String)value);
+      }
+      break;
+
+    case SHARED_COUNT:
+      if (value == null) {
+        unsetSharedCount();
+      } else {
+        setSharedCount((Long)value);
+      }
+      break;
+
+    case ORIGINAL_ENTITY_CREATION_TIME:
+      if (value == null) {
+        unsetOriginalEntityCreationTime();
+      } else {
+        setOriginalEntityCreationTime((Long)value);
+      }
+      break;
+
+    case CREATED_TIME:
+      if (value == null) {
+        unsetCreatedTime();
+      } else {
+        setCreatedTime((Long)value);
+      }
+      break;
+
+    case UPDATED_TIME:
+      if (value == null) {
+        unsetUpdatedTime();
+      } else {
+        setUpdatedTime((Long)value);
+      }
+      break;
+
+    }
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public Object getFieldValue(_Fields field) {
+    switch (field) {
+    case ENTITY_ID:
+      return getEntityId();
+
+    case DOMAIN_ID:
+      return getDomainId();
+
+    case ENTITY_TYPE_ID:
+      return getEntityTypeId();
+
+    case OWNER_ID:
+      return getOwnerId();
+
+    case PARENT_ENTITY_ID:
+      return getParentEntityId();
+
+    case NAME:
+      return getName();
+
+    case DESCRIPTION:
+      return getDescription();
+
+    case BINARY_DATA:
+      return getBinaryData();
+
+    case FULL_TEXT:
+      return getFullText();
+
+    case SHARED_COUNT:
+      return getSharedCount();
+
+    case ORIGINAL_ENTITY_CREATION_TIME:
+      return getOriginalEntityCreationTime();
+
+    case CREATED_TIME:
+      return getCreatedTime();
+
+    case UPDATED_TIME:
+      return getUpdatedTime();
+
+    }
+    throw new IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new IllegalArgumentException();
+    }
+
+    switch (field) {
+    case ENTITY_ID:
+      return isSetEntityId();
+    case DOMAIN_ID:
+      return isSetDomainId();
+    case ENTITY_TYPE_ID:
+      return isSetEntityTypeId();
+    case OWNER_ID:
+      return isSetOwnerId();
+    case PARENT_ENTITY_ID:
+      return isSetParentEntityId();
+    case NAME:
+      return isSetName();
+    case DESCRIPTION:
+      return isSetDescription();
+    case BINARY_DATA:
+      return isSetBinaryData();
+    case FULL_TEXT:
+      return isSetFullText();
+    case SHARED_COUNT:
+      return isSetSharedCount();
+    case ORIGINAL_ENTITY_CREATION_TIME:
+      return isSetOriginalEntityCreationTime();
+    case CREATED_TIME:
+      return isSetCreatedTime();
+    case UPDATED_TIME:
+      return isSetUpdatedTime();
+    }
+    throw new IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof Entity)
+      return this.equals((Entity)that);
+    return false;
+  }
+
+  public boolean equals(Entity that) {
+    if (that == null)
+      return false;
+    if (this == that)
+      return true;
+
+    boolean this_present_entityId = true && this.isSetEntityId();
+    boolean that_present_entityId = true && that.isSetEntityId();
+    if (this_present_entityId || that_present_entityId) {
+      if (!(this_present_entityId && that_present_entityId))
+        return false;
+      if (!this.entityId.equals(that.entityId))
+        return false;
+    }
+
+    boolean this_present_domainId = true && this.isSetDomainId();
+    boolean that_present_domainId = true && that.isSetDomainId();
+    if (this_present_domainId || that_present_domainId) {
+      if (!(this_present_domainId && that_present_domainId))
+        return false;
+      if (!this.domainId.equals(that.domainId))
+        return false;
+    }
+
+    boolean this_present_entityTypeId = true && this.isSetEntityTypeId();
+    boolean that_present_entityTypeId = true && that.isSetEntityTypeId();
+    if (this_present_entityTypeId || that_present_entityTypeId) {
+      if (!(this_present_entityTypeId && that_present_entityTypeId))
+        return false;
+      if (!this.entityTypeId.equals(that.entityTypeId))
+        return false;
+    }
+
+    boolean this_present_ownerId = true && this.isSetOwnerId();
+    boolean that_present_ownerId = true && that.isSetOwnerId();
+    if (this_present_ownerId || that_present_ownerId) {
+      if (!(this_present_ownerId && that_present_ownerId))
+        return false;
+      if (!this.ownerId.equals(that.ownerId))
+        return false;
+    }
+
+    boolean this_present_parentEntityId = true && this.isSetParentEntityId();
+    boolean that_present_parentEntityId = true && that.isSetParentEntityId();
+    if (this_present_parentEntityId || that_present_parentEntityId) {
+      if (!(this_present_parentEntityId && that_present_parentEntityId))
+        return false;
+      if (!this.parentEntityId.equals(that.parentEntityId))
+        return false;
+    }
+
+    boolean this_present_name = true && this.isSetName();
+    boolean that_present_name = true && that.isSetName();
+    if (this_present_name || that_present_name) {
+      if (!(this_present_name && that_present_name))
+        return false;
+      if (!this.name.equals(that.name))
+        return false;
+    }
+
+    boolean this_present_description = true && this.isSetDescription();
+    boolean that_present_description = true && that.isSetDescription();
+    if (this_present_description || that_present_description) {
+      if (!(this_present_description && that_present_description))
+        return false;
+      if (!this.description.equals(that.description))
+        return false;
+    }
+
+    boolean this_present_binaryData = true && this.isSetBinaryData();
+    boolean that_present_binaryData = true && that.isSetBinaryData();
+    if (this_present_binaryData || that_present_binaryData) {
+      if (!(this_present_binaryData && that_present_binaryData))
+        return false;
+      if (!this.binaryData.equals(that.binaryData))
+        return false;
+    }
+
+    boolean this_present_fullText = true && this.isSetFullText();
+    boolean that_present_fullText = true && that.isSetFullText();
+    if (this_present_fullText || that_present_fullText) {
+      if (!(this_present_fullText && that_present_fullText))
+        return false;
+      if (!this.fullText.equals(that.fullText))
+        return false;
+    }
+
+    boolean this_present_sharedCount = true && this.isSetSharedCount();
+    boolean that_present_sharedCount = true && that.isSetSharedCount();
+    if (this_present_sharedCount || that_present_sharedCount) {
+      if (!(this_present_sharedCount && that_present_sharedCount))
+        return false;
+      if (this.sharedCount != that.sharedCount)
+        return false;
+    }
+
+    boolean this_present_originalEntityCreationTime = true && this.isSetOriginalEntityCreationTime();
+    boolean that_present_originalEntityCreationTime = true && that.isSetOriginalEntityCreationTime();
+    if (this_present_originalEntityCreationTime || that_present_originalEntityCreationTime) {
+      if (!(this_present_originalEntityCreationTime && that_present_originalEntityCreationTime))
+        return false;
+      if (this.originalEntityCreationTime != that.originalEntityCreationTime)
+        return false;
+    }
+
+    boolean this_present_createdTime = true && this.isSetCreatedTime();
+    boolean that_present_createdTime = true && that.isSetCreatedTime();
+    if (this_present_createdTime || that_present_createdTime) {
+      if (!(this_present_createdTime && that_present_createdTime))
+        return false;
+      if (this.createdTime != that.createdTime)
+        return false;
+    }
+
+    boolean this_present_updatedTime = true && this.isSetUpdatedTime();
+    boolean that_present_updatedTime = true && that.isSetUpdatedTime();
+    if (this_present_updatedTime || that_present_updatedTime) {
+      if (!(this_present_updatedTime && that_present_updatedTime))
+        return false;
+      if (this.updatedTime != that.updatedTime)
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int hashCode = 1;
+
+    hashCode = hashCode * 8191 + ((isSetEntityId()) ? 131071 : 524287);
+    if (isSetEntityId())
+      hashCode = hashCode * 8191 + entityId.hashCode();
+
+    hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
+    if (isSetDomainId())
+      hashCode = hashCode * 8191 + domainId.hashCode();
+
+    hashCode = hashCode * 8191 + ((isSetEntityTypeId()) ? 131071 : 524287);
+    if (isSetEntityTypeId())
+      hashCode = hashCode * 8191 + entityTypeId.hashCode();
+
+    hashCode = hashCode * 8191 + ((isSetOwnerId()) ? 131071 : 524287);
+    if (isSetOwnerId())
+      hashCode = hashCode * 8191 + ownerId.hashCode();
+
+    hashCode = hashCode * 8191 + ((isSetParentEntityId()) ? 131071 : 524287);
+    if (isSetParentEntityId())
+      hashCode = hashCode * 8191 + parentEntityId.hashCode();
+
+    hashCode = hashCode * 8191 + ((isSetName()) ? 131071 : 524287);
+    if (isSetName())
+      hashCode = hashCode * 8191 + name.hashCode();
+
+    hashCode = hashCode * 8191 + ((isSetDescription()) ? 131071 : 524287);
+    if (isSetDescription())
+      hashCode = hashCode * 8191 + description.hashCode();
+
+    hashCode = hashCode * 8191 + ((isSetBinaryData()) ? 131071 : 524287);
+    if (isSetBinaryData())
+      hashCode = hashCode * 8191 + binaryData.hashCode();
+
+    hashCode = hashCode * 8191 + ((isSetFullText()) ? 131071 : 524287);
+    if (isSetFullText())
+      hashCode = hashCode * 8191 + fullText.hashCode();
+
+    hashCode = hashCode * 8191 + ((isSetSharedCount()) ? 131071 : 524287);
+    if (isSetSharedCount())
+      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(sharedCount);
+
+    hashCode = hashCode * 8191 + ((isSetOriginalEntityCreationTime()) ? 131071 : 524287);
+    if (isSetOriginalEntityCreationTime())
+      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(originalEntityCreationTime);
+
+    hashCode = hashCode * 8191 + ((isSetCreatedTime()) ? 131071 : 524287);
+    if (isSetCreatedTime())
+      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(createdTime);
+
+    hashCode = hashCode * 8191 + ((isSetUpdatedTime()) ? 131071 : 524287);
+    if (isSetUpdatedTime())
+      hashCode = hashCode * 8191 + org.apache.thrift.TBaseHelper.hashCode(updatedTime);
+
+    return hashCode;
+  }
+
+  @Override
+  public int compareTo(Entity other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+
+    lastComparison = Boolean.valueOf(isSetEntityId()).compareTo(other.isSetEntityId());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetEntityId()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityId, other.entityId);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetDomainId()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetEntityTypeId()).compareTo(other.isSetEntityTypeId());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetEntityTypeId()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityTypeId, other.entityTypeId);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetOwnerId()).compareTo(other.isSetOwnerId());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetOwnerId()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ownerId, other.ownerId);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetParentEntityId()).compareTo(other.isSetParentEntityId());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetParentEntityId()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.parentEntityId, other.parentEntityId);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetName()).compareTo(other.isSetName());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetName()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetDescription()).compareTo(other.isSetDescription());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetDescription()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.description, other.description);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetBinaryData()).compareTo(other.isSetBinaryData());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetBinaryData()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.binaryData, other.binaryData);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetFullText()).compareTo(other.isSetFullText());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetFullText()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.fullText, other.fullText);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetSharedCount()).compareTo(other.isSetSharedCount());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetSharedCount()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sharedCount, other.sharedCount);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetOriginalEntityCreationTime()).compareTo(other.isSetOriginalEntityCreationTime());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetOriginalEntityCreationTime()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.originalEntityCreationTime, other.originalEntityCreationTime);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetCreatedTime()).compareTo(other.isSetCreatedTime());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetCreatedTime()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.createdTime, other.createdTime);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetUpdatedTime()).compareTo(other.isSetUpdatedTime());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetUpdatedTime()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.updatedTime, other.updatedTime);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  @org.apache.thrift.annotation.Nullable
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    scheme(iprot).read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    scheme(oprot).write(oprot, this);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("Entity(");
+    boolean first = true;
+
+    if (isSetEntityId()) {
+      sb.append("entityId:");
+      if (this.entityId == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.entityId);
+      }
+      first = false;
+    }
+    if (isSetDomainId()) {
+      if (!first) sb.append(", ");
+      sb.append("domainId:");
+      if (this.domainId == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.domainId);
+      }
+      first = false;
+    }
+    if (isSetEntityTypeId()) {
+      if (!first) sb.append(", ");
+      sb.append("entityTypeId:");
+      if (this.entityTypeId == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.entityTypeId);
+      }
+      first = false;
+    }
+    if (isSetOwnerId()) {
+      if (!first) sb.append(", ");
+      sb.append("ownerId:");
+      if (this.ownerId == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ownerId);
+      }
+      first = false;
+    }
+    if (isSetParentEntityId()) {
+      if (!first) sb.append(", ");
+      sb.append("parentEntityId:");
+      if (this.parentEntityId == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.parentEntityId);
+      }
+      first = false;
+    }
+    if (isSetName()) {
+      if (!first) sb.append(", ");
+      sb.append("name:");
+      if (this.name == null) {
+        sb.append("null");
+      } else {
... 79299 lines suppressed ...