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:29 UTC

[airavata-custos] 34/45: updated the branch with master

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 757fe559cd26b0d2545ce784328ed6625c7acab1
Merge: d89e0de a0b6462
Author: Aarushi <aa...@gmail.com>
AuthorDate: Sat Aug 31 13:15:23 2019 -0400

    updated the branch with master

 .../{cpi => }/CustosAuthenticationService.java     |  238 +---
 .../cpi/CustosAuthenticationService.java           |  236 +---
 .../CustosAuthenticationServiceException.java      |    2 +-
 .../handler/CustosAuthenticationHandler.java       |    6 +-
 ...ava => AuthenticationServiceClientFactory.java} |    2 +-
 .../custos/commons/utils/ServiceRequest.java       |   36 +
 .../src/main/resources/custos-server.properties    |   11 +-
 custos-connectors/pom.xml                          |    5 +
 .../manager/CustosSecurityManager.java             |    2 +-
 .../manager/KeyCloakSecurityManager.java           |   30 +-
 .../main/resources/keystores/client_truststore.jks |  Bin 0 -> 963 bytes
 custos-profile-service/README                      |    3 +
 .../group-profile-api/pom.xml                      |   21 +
 .../group-profile-core/pom.xml                     |   22 +
 .../exceptions/GroupManagerServiceException.java   |   16 +
 .../profile/service/core/models/GroupModel.java    |   73 ++
 .../service/core/service/GroupProfileService.java  |  390 ++++++
 .../group-profile-service/pom.xml                  |   20 +
 .../services/core/TenantManagementInterface.java   |   10 +
 .../core/TenantManagementKeycloakImpl.java         |   30 +
 .../iam/admin/services/cpi/IamAdminServices.java   | 1255 ++++++++++++++++++--
 .../services/handler/IamAdminServicesHandler.java  |   34 +-
 .../repositories}/TenantProfileRepository.java     |   19 +-
 .../repositories/UserProfileRepository.java        |    3 +-
 .../src/main/resources/META-INF/persistence.xml    |    1 -
 .../profile/tenant/client/TenantProfileClient.java |   26 +
 .../profile/tenant/cpi/TenantProfileService.java   | 1109 ++++++++++++++++-
 .../handler/TenantProfileServiceHandler.java       |   19 +-
 .../user-profile-service/pom.xml                   |   14 +
 .../profile/user/client/UserProfileClient.java     |    4 +
 .../profile/user/cpi/UserProfileService.java       |  470 +-------
 .../user/handler/UserProfileServiceHandler.java    |   42 +-
 .../test/java/TestUserProfileServiceHandler.java   |  120 ++
 .../sharing-service-api/pom.xml                    |   23 +
 .../custos/sharing/service/api/AppConfig.java      |   22 +
 .../custos/sharing/service/api/Application.java    |   32 +
 .../api/constants/SharingRegistryEndpoints.java    |   22 +
 .../service/api/controllers/AccessController.java  |   71 ++
 .../service/api/controllers/DomainsController.java |   79 ++
 .../service/api/controllers/EntityController.java  |  117 ++
 .../api/controllers/EntityTypeController.java      |   95 ++
 .../service/api/controllers/GroupController.java   |  244 ++++
 .../api/controllers/PermissionTypeController.java  |   94 ++
 .../service/api/controllers/UsersController.java   |   95 ++
 .../sharing-service-core/pom.xml                   |   58 +
 .../service/core/db/entities/DomainEntity.java     |  116 ++
 .../service/core/db/entities/EntityEntity.java     |  219 ++++
 .../sharing/service/core/db/entities/EntityPK.java |   76 ++
 .../service/core/db/entities/EntityTypeEntity.java |  130 ++
 .../service/core/db/entities/EntityTypePK.java     |   76 ++
 .../service/core/db/entities/GroupAdminEntity.java |   80 ++
 .../service/core/db/entities/GroupAdminPK.java     |   66 +
 .../core/db/entities/GroupMembershipEntity.java    |  126 ++
 .../core/db/entities/GroupMembershipPK.java        |   88 ++
 .../core/db/entities/PermissionTypeEntity.java     |  128 ++
 .../service/core/db/entities/PermissionTypePK.java |   76 ++
 .../service/core/db/entities/SharingEntity.java    |  149 +++
 .../service/core/db/entities/SharingPK.java        |  116 ++
 .../service/core/db/entities/UserEntity.java       |  161 +++
 .../service/core/db/entities/UserGroupEntity.java  |  178 +++
 .../service/core/db/entities/UserGroupPK.java      |   75 ++
 .../sharing/service/core/db/entities/UserPK.java   |   75 ++
 .../core/db/repositories/AbstractRepository.java   |  169 +++
 .../core/db/repositories/DomainRepository.java     |   33 +
 .../core/db/repositories/EntityRepository.java     |  180 +++
 .../core/db/repositories/EntityTypeRepository.java |   34 +
 .../core/db/repositories/GroupAdminRepository.java |   17 +
 .../db/repositories/GroupMembershipRepository.java |  105 ++
 .../db/repositories/PermissionTypeRepository.java  |   52 +
 .../core/db/repositories/SharingRepository.java    |  114 ++
 .../core/db/repositories/UserGroupRepository.java  |   95 ++
 .../core/db/repositories/UserRepository.java       |   79 ++
 .../sharing/service/core/db/utils/Committer.java   |   26 +
 .../sharing/service/core/db/utils/DBConstants.java |  106 ++
 .../sharing/service/core/db/utils/JPAUtils.java    |   35 +
 .../core/db/utils/ObjectMapperSingleton.java       |   38 +
 .../core/db/utils/SharingRegistryDBInitConfig.java |   50 +
 .../core/db/utils/SharingRegistryJDBCConfig.java   |   67 ++
 .../core/exceptions/DuplicateEntryException.java   |   15 +
 .../core/exceptions/ResourceNotFoundException.java |   16 +
 .../core/exceptions/SharingRegistryException.java  |   16 +
 .../custos/sharing/service/core/models/Domain.java |   49 +
 .../custos/sharing/service/core/models/Entity.java |  121 ++
 .../service/core/models/EntitySearchField.java     |   14 +
 .../sharing/service/core/models/EntityType.java    |   58 +
 .../sharing/service/core/models/GroupAdmin.java    |   33 +
 .../service/core/models/GroupCardinality.java      |    6 +
 .../service/core/models/GroupChildType.java        |    6 +
 .../service/core/models/GroupMembership.java       |   60 +
 .../sharing/service/core/models/GroupType.java     |    6 +
 .../service/core/models/PermissionType.java        |   60 +
 .../service/core/models/SearchCondition.java       |   10 +
 .../service/core/models/SearchCriteria.java        |   31 +
 .../sharing/service/core/models/Sharing.java       |   78 ++
 .../sharing/service/core/models/SharingType.java   |    7 +
 .../custos/sharing/service/core/models/User.java   |   85 ++
 .../sharing/service/core/models/UserGroup.java     |   97 ++
 .../core/service/SharingRegistryService.java       | 1216 +++++++++++++++++++
 ide-integration/README.md                          |   64 +
 ide-integration/custos-services/pom.xml            |   15 +
 .../server/start}/CustosAPIServerStarted.java      |    4 +-
 .../src/main/resources/custos-server.properties    |   28 +-
 .../database_scripts/init/01-databases.sql         |   43 +-
 .../user-profile-catalog-derby.sql                 |   30 -
 .../user-profile-catalog-mysql.sql                 |   30 -
 .../src/main/resources/docker-compose.yml          |    4 +-
 .../main/resources/keycloak/Default-export.json    |    0
 .../main/resources/keycloak/Default-export.json.bk |    0
 .../src/main/resources/keycloak/standalone.xml     |    2 +-
 .../src/main/resources/keystores/custos.jks        |  Bin 0 -> 2252 bytes
 .../src/main/resources}/log4j.properties           |    8 +-
 ide-integration/pom.xml                            |   17 +
 ide-integration/samples/commons/pom.xml            |   15 +
 .../org/apache/samples/common/SamplesCommon.java   |   60 +
 .../custos-authentication-service-samples/pom.xml  |   23 +
 .../sample/CustosAuthenticationServiceSample.java  |   64 +
 .../src/main/resources/log4j.properties            |   10 +-
 .../samples/custos-profile-service-samples/pom.xml |   22 +
 .../service/samples/TenantProfileSample.java       |   80 ++
 .../profile/service/samples/UserProfileSample.java |  160 +++
 .../samples/utils/ProfileServiceClientUtil.java    |   63 +
 .../src/main/resources/log4j.properties            |   10 +-
 .../resources/profile-client-sample.properties     |   29 +
 ide-integration/samples/pom.xml                    |   20 +
 .../src/main/resources/keystores/airavata.jks      |  Bin 2679 -> 0 bytes
 .../src/main/resources/keystores/airavata_sym.jks  |  Bin 501 -> 0 bytes
 .../main/resources/keystores/client_truststore.jks |  Bin 1027 -> 0 bytes
 pom.xml                                            |    3 +-
 .../authentication-service-cpi.thrift              |    2 +-
 .../iam-admin-services-cpi.thrift                  |    6 +-
 .../profile-tenant/profile-tenant-cpi.thrift       |    4 +
 .../profile-user/profile-user-cpi.thrift           |    8 +-
 132 files changed, 10015 insertions(+), 1149 deletions(-)

diff --cc custos-commons/src/main/java/org/apache/custos/commons/utils/ServiceRequest.java
index 0000000,0000000..23e0061
new file mode 100644
--- /dev/null
+++ b/custos-commons/src/main/java/org/apache/custos/commons/utils/ServiceRequest.java
@@@ -1,0 -1,0 +1,36 @@@
++package org.apache.custos.commons.utils;
++
++import com.fasterxml.jackson.databind.ObjectMapper;
++import org.apache.http.entity.ContentType;
++import org.apache.http.entity.StringEntity;
++import org.springframework.stereotype.Component;
++
++import java.io.BufferedReader;
++import java.io.InputStreamReader;
++import java.net.HttpURLConnection;
++import java.net.URL;
++import java.util.Map;
++
++@Component
++public class ServiceRequest {
++
++    public String httpGet(String baseUrl, String requestUrl) throws Exception{
++            StringBuilder result = new StringBuilder();
++            URL url = new URL(baseUrl + requestUrl);
++            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
++            conn.setRequestMethod("GET");
++            BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
++            String line;
++            while ((line = rd.readLine()) != null) {
++                result.append(line);
++            }
++            rd.close();
++            return result.toString();
++    }
++
++    public void httpPost(String baseUrl, String requestUrl, Object jsonObject){
++//        ObjectMapper obj = new ObjectMapper();
++//        String postBodyString = obj.writeValueAsString(jsonObject);
++//        StringEntity requestEntity = new StringEntity(postBodyString, ContentType.APPLICATION_JSON);
++    }
++}
diff --cc custos-profile-service/README
index 0000000,0000000..9d83e76
new file mode 100644
--- /dev/null
+++ b/custos-profile-service/README
@@@ -1,0 -1,0 +1,3 @@@
++Custos Profile Service
++
++The thrift files associated with Profile services are in thrift-interfaces/profile-service folder
diff --cc custos-profile-service/group-profile-service/group-profile-api/pom.xml
index 0000000,0000000..1c5e69f
new file mode 100644
--- /dev/null
+++ b/custos-profile-service/group-profile-service/group-profile-api/pom.xml
@@@ -1,0 -1,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>group-profile-service</artifactId>
++        <groupId>org.apache.custos</groupId>
++        <version>1.0-SNAPSHOT</version>
++    </parent>
++    <modelVersion>4.0.0</modelVersion>
++
++    <artifactId>group-profile-api</artifactId>
++    <dependencies>
++        <dependency>
++            <groupId>org.apache.custos</groupId>
++            <artifactId>group-profile-core</artifactId>
++            <version>${project.version}</version>
++        </dependency>
++    </dependencies>
++
++</project>
diff --cc custos-profile-service/group-profile-service/group-profile-core/pom.xml
index 0000000,0000000..49575e0
new file mode 100644
--- /dev/null
+++ b/custos-profile-service/group-profile-service/group-profile-core/pom.xml
@@@ -1,0 -1,0 +1,22 @@@
++<?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>group-profile-service</artifactId>
++        <groupId>org.apache.custos</groupId>
++        <version>1.0-SNAPSHOT</version>
++    </parent>
++    <modelVersion>4.0.0</modelVersion>
++
++    <artifactId>group-profile-core</artifactId>
++    <dependencies>
++        <dependency>
++            <groupId>org.apache.custos</groupId>
++            <artifactId>user-profile-service</artifactId>
++            <version>${project.version}</version>
++        </dependency>
++    </dependencies>
++
++
++</project>
diff --cc custos-profile-service/group-profile-service/group-profile-core/src/main/java/org/apache/custos/profile/service/core/exceptions/GroupManagerServiceException.java
index 0000000,0000000..6de6312
new file mode 100644
--- /dev/null
+++ b/custos-profile-service/group-profile-service/group-profile-core/src/main/java/org/apache/custos/profile/service/core/exceptions/GroupManagerServiceException.java
@@@ -1,0 -1,0 +1,16 @@@
++package org.apache.custos.profile.service.core.exceptions;
++
++import org.springframework.http.HttpStatus;
++import org.springframework.web.bind.annotation.ResponseStatus;
++
++@ResponseStatus(value= HttpStatus.INTERNAL_SERVER_ERROR, reason = "Request cannot be completed due to server error")
++public class GroupManagerServiceException extends RuntimeException {
++
++    public GroupManagerServiceException(String errorMessage) {
++        super(errorMessage);
++    }
++
++    public GroupManagerServiceException(String errorMessage, Throwable err) {
++        super(errorMessage, err);
++    }
++}
diff --cc custos-profile-service/group-profile-service/group-profile-core/src/main/java/org/apache/custos/profile/service/core/models/GroupModel.java
index 0000000,0000000..c36d520
new file mode 100644
--- /dev/null
+++ b/custos-profile-service/group-profile-service/group-profile-core/src/main/java/org/apache/custos/profile/service/core/models/GroupModel.java
@@@ -1,0 -1,0 +1,73 @@@
++package org.apache.custos.profile.service.core.models;
++
++import java.util.List;
++
++public class GroupModel {
++    private String id;
++    private String name;
++    private String ownerId;
++    private String description;
++    private String gatewayId;
++    private List<String> members;
++    /**
++     * Note: each admin must also be a member of the group.
++     */
++    private List<String> admins;
++
++    public String getId() {
++        return id;
++    }
++
++    public void setId(String id) {
++        this.id = id;
++    }
++
++    public String getName() {
++        return name;
++    }
++
++    public void setName(String name) {
++        this.name = name;
++    }
++
++    public String getOwnerId() {
++        return ownerId;
++    }
++
++    public void setOwnerId(String ownerId) {
++        this.ownerId = ownerId;
++    }
++
++    public String getDescription() {
++        return description;
++    }
++
++    public void setDescription(String description) {
++        this.description = description;
++    }
++
++    public List<String> getMembers() {
++        return members;
++    }
++
++    public void setMembers(List<String> members) {
++        this.members = members;
++    }
++
++    public List<String> getAdmins() {
++        return admins;
++    }
++
++    public void setAdmins(List<String> admins) {
++        this.admins = admins;
++    }
++
++
++    public String getGatewayId() {
++        return gatewayId;
++    }
++
++    public void setGatewayId(String gatewayId) {
++        this.gatewayId = gatewayId;
++    }
++}
diff --cc custos-profile-service/group-profile-service/group-profile-core/src/main/java/org/apache/custos/profile/service/core/service/GroupProfileService.java
index 0000000,0000000..f4843cd
new file mode 100644
--- /dev/null
+++ b/custos-profile-service/group-profile-service/group-profile-core/src/main/java/org/apache/custos/profile/service/core/service/GroupProfileService.java
@@@ -1,0 -1,0 +1,390 @@@
++//package org.apache.custos.profile.service.core.service;
++//
++//import org.apache.custos.commons.utils.ServiceRequest;
++//import org.apache.custos.profile.user.core.repositories.UserProfileRepository;
++//import org.apache.custos.sharing.service.api.constants.SharingRegistryEndpoints;
++//import org.apache.custos.sharing.service.core.models.GroupCardinality;
++//import org.apache.custos.sharing.service.core.models.GroupType;
++//import org.apache.custos.sharing.service.core.models.UserGroup;
++//import org.apache.custos.profile.service.core.models.*;
++//import org.apache.custos.profile.service.core.exceptions.*;
++//import org.slf4j.Logger;
++//import org.slf4j.LoggerFactory;
++//import org.springframework.beans.factory.annotation.Autowired;
++//
++//import java.util.ArrayList;
++//import java.util.List;
++//import java.util.UUID;
++//import java.util.stream.Collectors;
++//
++//public class GroupProfileService {
++//
++//    @Autowired
++//    private static ServiceRequest serviceRequest;
++//
++//    @Autowired
++//    private static SharingRegistryEndpoints SharingRegistryEndpoints;
++//
++//    private static final Logger logger = LoggerFactory.getLogger(GroupProfileService.class);
++//    private static final String GROUP_MANAGER_CPI_VERSION = "1.0";
++//    private UserProfileRepository userProfileRepository = new UserProfileRepository();
++//    private static final String SHARING_SERVICE_BASE_URL = SharingRegistryEndpoints.BASE_URL;
++//
++//    public String getAPIVersion() {
++//        return GROUP_MANAGER_CPI_VERSION;
++//    }
++//
++//    public String createGroup(GroupModel groupModel, String gatewayId, String userId) throws GroupManagerServiceException{
++//        try {
++//
++//            UserGroup sharingUserGroup = new UserGroup();
++//            sharingUserGroup.setGroupId(UUID.randomUUID().toString());
++//            sharingUserGroup.setName(groupModel.getName());
++//            sharingUserGroup.setDescription(groupModel.getDescription());
++//            sharingUserGroup.setGroupType(GroupType.USER_LEVEL_GROUP);
++//            sharingUserGroup.setGroupCardinality(GroupCardinality.MULTI_USER);
++//            sharingUserGroup.setDomainId(gatewayId);
++//            sharingUserGroup.setOwnerId(userId);
++//
++//            String groupId = serviceRequest.httpPost(SHARING_SERVICE_BASE_URL, SharingRegistryEndpoints.CREATE_GROUP, );
++//            //TODO: should happen in one rest call
++//            //internalAddUsersToGroup(sharingClient, gatewayId, groupModel.getMembers(), groupId);
++//            //addGroupAdmins(authzToken,groupId,groupModel.getAdmins());
++//            return groupId;
++//        }
++//        catch (Exception e) {
++//            String msg = "Error Creating Group" ;
++//            logger.error(msg, e);
++//            GroupManagerServiceException exception = new GroupManagerServiceException(msg + " More info : " + e.getMessage());
++//            throw exception;
++//        }
++//    }
++//
++//    public boolean updateGroup(GroupModel groupModel, String gatewayId, String userId) throws GroupManagerServiceException{
++//        try {
++//            if (!(sharingClient.hasOwnerAccess(domainId, groupModel.getId(), userId)
++//                    || sharingClient.hasAdminAccess(domainId, groupModel.getId(), userId))) {
++//                throw new GroupManagerServiceException("User does not have permission to update group");
++//            }
++//
++//            UserGroup sharingUserGroup = new UserGroup();
++//            sharingUserGroup.setGroupId(groupModel.getId());
++//            sharingUserGroup.setName(groupModel.getName());
++//            sharingUserGroup.setDescription(groupModel.getDescription());
++//            sharingUserGroup.setGroupType(GroupType.USER_LEVEL_GROUP);
++//            sharingUserGroup.setDomainId(gatewayId);
++//
++//            //adding and removal of users should be handle separately??
++//            String response = serviceRequest.httpPut(SHARING_SERVICE_BASE_URL, SharingRegistryEndpoints.UPDATE_GROUP);
++//        }
++//        catch (Exception e) {
++//            String msg = "Error Updating Group" ;
++//            logger.error(msg, e);
++//            GroupManagerServiceException exception = new GroupManagerServiceException(msg + " More info : " + e.getMessage());
++//            throw exception;
++//        }
++//    }
++//
++//    public boolean deleteGroup(AuthzToken authzToken, String groupId, String ownerId) throws GroupManagerServiceException, AuthorizationException, TException {
++//        try {
++//            SharingRegistryService.Client sharingClient = getSharingRegistryServiceClient();
++//            String userId = getUserId(authzToken);
++//            String domainId = getDomainId(authzToken);
++//            if (!(sharingClient.hasOwnerAccess(domainId, groupId, userId))) {
++//                throw new GroupManagerServiceException("User does not have permission to delete group");
++//            }
++//
++//            sharingClient.deleteGroup(getDomainId(authzToken), groupId);
++//            return true;
++//        }
++//        catch (Exception e) {
++//            String msg = "Error Deleting Group. Group ID: " + groupId ;
++//            logger.error(msg, e);
++//            GroupManagerServiceException exception = new GroupManagerServiceException();
++//            exception.setMessage(msg + " More info : " + e.getMessage());
++//            throw exception;
++//        }
++//    }
++//
++//    @Override
++//    @SecurityCheck
++//    public GroupModel getGroup(AuthzToken authzToken, String groupId) throws GroupManagerServiceException, AuthorizationException, TException {
++//        try {
++//            SharingRegistryService.Client sharingClient = getSharingRegistryServiceClient();
++//            final String domainId = getDomainId(authzToken);
++//            UserGroup userGroup = sharingClient.getGroup(domainId, groupId);
++//
++//            GroupModel groupModel = convertToGroupModel(userGroup, sharingClient);
++//
++//            return groupModel;
++//        }
++//        catch (Exception e) {
++//            String msg = "Error Retreiving Group. Group ID: " + groupId ;
++//            logger.error(msg, e);
++//            GroupManagerServiceException exception = new GroupManagerServiceException();
++//            exception.setMessage(msg + " More info : " + e.getMessage());
++//            throw exception;
++//        }
++//    }
++//
++//    @Override
++//    @SecurityCheck
++//    public List<GroupModel> getGroups(AuthzToken authzToken) throws GroupManagerServiceException, AuthorizationException, TException {
++//        final String domainId = getDomainId(authzToken);
++//        SharingRegistryService.Client sharingClient = null;
++//        try {
++//            sharingClient = getSharingRegistryServiceClient();
++//            List<UserGroup> userGroups = sharingClient.getGroups(domainId, 0, -1);
++//
++//            return convertToGroupModels(userGroups, sharingClient);
++//        }
++//        catch (Exception e) {
++//            String msg = "Error Retrieving Groups. Domain ID: " + domainId;
++//            logger.error(msg, e);
++//            GroupManagerServiceException exception = new GroupManagerServiceException();
++//            exception.setMessage(msg + " More info : " + e.getMessage());
++//            throw exception;
++//        } finally {
++//            closeSharingClient(sharingClient);
++//        }
++//    }
++//
++//    @Override
++//    @SecurityCheck
++//    public List<GroupModel> getAllGroupsUserBelongs(AuthzToken authzToken, String userName) throws GroupManagerServiceException, AuthorizationException, TException {
++//        try {
++//            SharingRegistryService.Client sharingClient = getSharingRegistryServiceClient();
++//            List<GroupModel> groupModels = new ArrayList<GroupModel>();
++//            final String domainId = getDomainId(authzToken);
++//            List<UserGroup> userGroups = sharingClient.getAllMemberGroupsForUser(domainId, userName);
++//
++//            return convertToGroupModels(userGroups, sharingClient);
++//        }
++//        catch (Exception e) {
++//            String msg = "Error Retreiving All Groups for User. User ID: " + userName ;
++//            logger.error(msg, e);
++//            GroupManagerServiceException exception = new GroupManagerServiceException();
++//            exception.setMessage(msg + " More info : " + e.getMessage());
++//            throw exception;
++//        }
++//    }
++//
++//    @Override
++//    public boolean addUsersToGroup(AuthzToken authzToken, List<String> userIds, String groupId) throws GroupManagerServiceException, AuthorizationException, TException {
++//        try {
++//            SharingRegistryService.Client sharingClient = getSharingRegistryServiceClient();
++//            String userId = getUserId(authzToken);
++//            String domainId = getDomainId(authzToken);
++//            if (!(sharingClient.hasOwnerAccess(domainId, groupId, userId)
++//                    || sharingClient.hasAdminAccess(domainId, groupId, userId))) {
++//                throw new GroupManagerServiceException("User does not have access to add users to the group");
++//            }
++//            return internalAddUsersToGroup(sharingClient, domainId, userIds, groupId);
++//
++//        } catch (Exception e) {
++//            String msg = "Error adding users to group. Group ID: " + groupId ;
++//            logger.error(msg, e);
++//            GroupManagerServiceException exception = new GroupManagerServiceException();
++//            exception.setMessage(msg + " More info : " + e.getMessage());
++//            throw exception;
++//        }
++//    }
++//
++//    @Override
++//    public boolean removeUsersFromGroup(AuthzToken authzToken, List<String> userIds, String groupId) throws GroupManagerServiceException, AuthorizationException, TException {
++//        try {
++//            SharingRegistryService.Client sharingClient = getSharingRegistryServiceClient();
++//            String userId = getUserId(authzToken);
++//            String domainId = getDomainId(authzToken);
++//            if (!(sharingClient.hasOwnerAccess(domainId, groupId, userId)
++//                    || sharingClient.hasAdminAccess(domainId, groupId, userId))) {
++//                throw new GroupManagerServiceException("User does not have access to remove users to the group");
++//            }
++//            return sharingClient.removeUsersFromGroup(domainId, userIds, groupId);
++//        } catch (Exception e) {
++//            String msg = "Error remove users to group. Group ID: " + groupId ;
++//            logger.error(msg, e);
++//            GroupManagerServiceException exception = new GroupManagerServiceException();
++//            exception.setMessage(msg + " More info : " + e.getMessage());
++//            throw exception;
++//        }
++//    }
++//
++//    @Override
++//    @SecurityCheck
++//    public boolean transferGroupOwnership(AuthzToken authzToken, String groupId, String newOwnerId) throws GroupManagerServiceException, AuthorizationException, TException {
++//        try{
++//            SharingRegistryService.Client sharingClient = getSharingRegistryServiceClient();
++//            String userId = getUserId(authzToken);
++//            String domainId = getDomainId(authzToken);
++//            if (!(sharingClient.hasOwnerAccess(domainId, groupId, userId))) {
++//                throw new GroupManagerServiceException("User does not have Owner permission to transfer group ownership");
++//            }
++//            return sharingClient.transferGroupOwnership(getDomainId(authzToken), groupId, newOwnerId);
++//        }
++//        catch (Exception e) {
++//            String msg = "Error Transferring Group Ownership";
++//            logger.error(msg, e);
++//            GroupManagerServiceException exception = new GroupManagerServiceException();
++//            exception.setMessage(msg + " More info : " + e.getMessage());
++//            throw exception;
++//        }
++//
++//    }
++//
++//    @Override
++//    @SecurityCheck
++//    public boolean addGroupAdmins(AuthzToken authzToken, String groupId, List<String> adminIds) throws GroupManagerServiceException, AuthorizationException, TException {
++//        try {
++//            SharingRegistryService.Client sharingClient = getSharingRegistryServiceClient();
++//            String userId = getUserId(authzToken);
++//            String domainId = getDomainId(authzToken);
++//            if (!(sharingClient.hasOwnerAccess(domainId, groupId, userId))) {
++//                throw new GroupManagerServiceException("User does not have Owner permission to add group admins");
++//            }
++//            return sharingClient.addGroupAdmins(getDomainId(authzToken), groupId, adminIds);
++//        }
++//        catch (Exception e) {
++//            String msg = "Error Adding Admins to Group. Group ID: " + groupId;
++//            logger.error(msg, e);
++//            GroupManagerServiceException exception = new GroupManagerServiceException();
++//            exception.setMessage(msg + " More info : " + e.getMessage());
++//            throw exception;
++//        }
++//    }
++//
++//    @Override
++//    @SecurityCheck
++//    public boolean removeGroupAdmins(AuthzToken authzToken, String groupId, List<String> adminIds) throws GroupManagerServiceException, AuthorizationException, TException {
++//        try {
++//            SharingRegistryService.Client sharingClient = getSharingRegistryServiceClient();
++//            String userId = getUserId(authzToken);
++//            String domainId = getDomainId(authzToken);
++//            if (!(sharingClient.hasOwnerAccess(domainId, groupId, userId))) {
++//                throw new GroupManagerServiceException("User does not have Owner permission to remove group admins");
++//            }
++//            return sharingClient.removeGroupAdmins(getDomainId(authzToken), groupId, adminIds);
++//        }
++//        catch (Exception e) {
++//            String msg = "Error Removing Admins from the Group. Group ID: " + groupId;
++//            logger.error(msg, e);
++//            GroupManagerServiceException exception = new GroupManagerServiceException();
++//            exception.setMessage(msg + " More info : " + e.getMessage());
++//            throw exception;
++//        }
++//    }
++//
++//    @Override
++//    @SecurityCheck
++//    public boolean hasAdminAccess(AuthzToken authzToken, String groupId, String adminId) throws GroupManagerServiceException, AuthorizationException, TException {
++//        try {
++//            SharingRegistryService.Client sharingClient = getSharingRegistryServiceClient();
++//            return sharingClient.hasAdminAccess(getDomainId(authzToken), groupId, adminId);
++//        }
++//        catch (Exception e) {
++//            String msg = "Error Checking Admin Access for the Group. Group ID: " + groupId + " Admin ID: " + adminId;
++//            logger.error(msg, e);
++//            GroupManagerServiceException exception = new GroupManagerServiceException();
++//            exception.setMessage(msg + " More info : " + e.getMessage());
++//            throw exception;
++//        }
++//    }
++//
++//    @Override
++//    @SecurityCheck
++//    public boolean hasOwnerAccess(AuthzToken authzToken, String groupId, String ownerId) throws GroupManagerServiceException, AuthorizationException, TException {
++//        try {
++//            SharingRegistryService.Client sharingClient = getSharingRegistryServiceClient();
++//            return sharingClient.hasOwnerAccess(getDomainId(authzToken), groupId, ownerId);
++//        }
++//        catch (Exception e) {
++//            String msg = "Error Checking Owner Access for the Group. Group ID: " + groupId + " Owner ID: " + ownerId;
++//            logger.error(msg, e);
++//            GroupManagerServiceException exception = new GroupManagerServiceException();
++//            exception.setMessage(msg + " More info : " + e.getMessage());
++//            throw exception;
++//        }
++//    }
++//
++//    // TODO: replace these methods with ThriftClientPool (see AIRAVATA-2607)
++//    private SharingRegistryService.Client getSharingRegistryServiceClient() throws TException, ApplicationSettingsException {
++//        final int serverPort = Integer.parseInt(ServerSettings.getSharingRegistryPort());
++//        final String serverHost = ServerSettings.getSharingRegistryHost();
++//        try {
++//            return SharingRegistryServiceClientFactory.createSharingRegistryClient(serverHost, serverPort);
++//        } catch (SharingRegistryException e) {
++//            throw new TException("Unable to create sharing registry client...", e);
++//        }
++//    }
++//
++//    private String getDomainId(AuthzToken authzToken) {
++//        return authzToken.getClaimsMap().get(Constants.GATEWAY_ID);
++//    }
++//
++//    private String getUserId(AuthzToken authzToken) {
++//        return authzToken.getClaimsMap().get(Constants.USER_NAME) + "@" + getDomainId(authzToken);
++//    }
++//
++//    private List<GroupModel> convertToGroupModels(List<UserGroup> userGroups, SharingRegistryService.Client sharingClient) throws TException {
++//
++//        List<GroupModel> groupModels = new ArrayList<>();
++//
++//        for (UserGroup userGroup: userGroups) {
++//            GroupModel groupModel = convertToGroupModel(userGroup, sharingClient);
++//
++//            groupModels.add(groupModel);
++//        }
++//        return groupModels;
++//    }
++//
++//    private GroupModel convertToGroupModel(UserGroup userGroup, SharingRegistryService.Client sharingClient) throws TException {
++//        GroupModel groupModel = new GroupModel();
++//        groupModel.setId(userGroup.getGroupId());
++//        groupModel.setName(userGroup.getName());
++//        groupModel.setDescription(userGroup.getDescription());
++//        groupModel.setOwnerId(userGroup.getOwnerId());
++//        final List<String> admins = userGroup.getGroupAdmins().stream()
++//                .map(groupAdmin -> groupAdmin.getAdminId())
++//                .collect(Collectors.toList());
++//        groupModel.setAdmins(admins);
++//
++//        sharingClient.getGroupMembersOfTypeUser(userGroup.getDomainId(), userGroup.getGroupId(), 0, -1).stream().forEach(user->
++//                groupModel.addToMembers(user.getUserId())
++//        );
++//        return groupModel;
++//    }
++//
++//    private void closeSharingClient(SharingRegistryService.Client sharingClient) {
++//        if (sharingClient != null) {
++//            if (sharingClient.getInputProtocol().getTransport().isOpen()) {
++//                sharingClient.getInputProtocol().getTransport().close();
++//            }
++//            if (sharingClient.getOutputProtocol().getTransport().isOpen()) {
++//                sharingClient.getOutputProtocol().getTransport().close();
++//            }
++//        }
++//    }
++//
++//    private boolean internalAddUsersToGroup(SharingRegistryService.Client sharingClient, String domainId, List<String> userIds, String groupId) throws SharingRegistryException, TException {
++//
++//        // FIXME: workaround for UserProfiles that failed to sync to the sharing
++//        // registry: create any missing users in the sharing registry
++//        for (String userId : userIds) {
++//            if (!sharingClient.isUserExists(domainId, userId)) {
++//                User user = new User();
++//                user.setDomainId(domainId);
++//                user.setUserId(userId);
++//                UserProfile userProfile = userProfileRepository.get(userId);
++//                user.setUserName(userProfile.getUserId());
++//                user.setCreatedTime(userProfile.getCreationTime());
++//                user.setEmail(userProfile.getEmailsSize() > 0 ? userProfile.getEmails().get(0) : null);
++//                user.setFirstName(userProfile.getFirstName());
++//                user.setLastName(userProfile.getLastName());
++//                sharingClient.createUser(user);
++//            }
++//        }
++//        return sharingClient.addUsersToGroup(domainId, userIds, groupId);
++//    }
++//}
++//
++//}
diff --cc custos-profile-service/group-profile-service/pom.xml
index 0000000,0000000..7d58503
new file mode 100644
--- /dev/null
+++ b/custos-profile-service/group-profile-service/pom.xml
@@@ -1,0 -1,0 +1,20 @@@
++<?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-profile-service</artifactId>
++        <groupId>org.apache.custos</groupId>
++        <version>1.0-SNAPSHOT</version>
++    </parent>
++    <modelVersion>4.0.0</modelVersion>
++
++    <artifactId>group-profile-service</artifactId>
++    <packaging>pom</packaging>
++    <modules>
++        <module>group-profile-api</module>
++        <module>group-profile-core</module>
++    </modules>
++
++
++</project>
diff --cc custos-sharing-registry-service/sharing-service-api/pom.xml
index 0000000,0000000..5811ff9
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-api/pom.xml
@@@ -1,0 -1,0 +1,23 @@@
++<?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-sharing-registry-service</artifactId>
++        <groupId>org.apache.custos</groupId>
++        <version>1.0-SNAPSHOT</version>
++    </parent>
++    <modelVersion>4.0.0</modelVersion>
++
++    <artifactId>sharing-service-api</artifactId>
++    <dependencies>
++        <dependency>
++            <groupId>org.apache.custos</groupId>
++            <artifactId>sharing-service-core</artifactId>
++            <version>1.0-SNAPSHOT</version>
++            <scope>compile</scope>
++        </dependency>
++    </dependencies>
++
++
++</project>
diff --cc custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/AppConfig.java
index 0000000,0000000..ecc0943
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/AppConfig.java
@@@ -1,0 -1,0 +1,22 @@@
++package org.apache.custos.sharing.service.api;
++
++import org.apache.custos.commons.exceptions.ApplicationSettingsException;
++import org.apache.custos.sharing.service.core.db.utils.SharingRegistryDBInitConfig;
++import org.apache.custos.sharing.service.core.service.SharingRegistryService;
++import org.springframework.beans.factory.annotation.Autowired;
++import org.springframework.context.annotation.Bean;
++import org.springframework.context.annotation.Configuration;
++
++@Configuration
++public class AppConfig {
++    @Autowired
++    SharingRegistryDBInitConfig sharingRegistryDBInitConfig;
++    @Bean
++    public SharingRegistryDBInitConfig SharingRegistryDBInitConfigBeanMapper(){
++        return new SharingRegistryDBInitConfig();
++    }
++    @Bean
++    public SharingRegistryService SharingRegistryServiceBeanMapper() throws ApplicationSettingsException {
++        return new SharingRegistryService(sharingRegistryDBInitConfig);
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/Application.java
index 0000000,0000000..ebdd989
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/Application.java
@@@ -1,0 -1,0 +1,32 @@@
++/*
++ *
++ * 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.service.api;
++
++import org.springframework.boot.SpringApplication;
++import org.springframework.boot.autoconfigure.SpringBootApplication;
++import org.springframework.context.annotation.ComponentScan;
++
++@SpringBootApplication
++@ComponentScan(basePackages = {"org.apache.custos.sharing.service.api.controllers"})
++public class Application {
++    public static void main(String[] args){
++        SpringApplication.run(Application.class, args);
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/constants/SharingRegistryEndpoints.java
index 0000000,0000000..27f1b8c
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/constants/SharingRegistryEndpoints.java
@@@ -1,0 -1,0 +1,22 @@@
++package org.apache.custos.sharing.service.api.constants;
++
++import org.apache.custos.commons.exceptions.ApplicationSettingsException;
++import org.apache.custos.commons.utils.ServerSettings;
++import org.springframework.stereotype.Component;
++
++@Component
++public class SharingRegistryEndpoints {
++
++    public String BASE_URL;
++
++    //group APIs
++    public String CREATE_GROUP = "/group";
++    public String UPDATE_GROUP = "/group";
++    public String IS_GROUP_EXISTS = "/group/exists/id/{groupId}/domain/{domainId}";
++    public String DELETE_GROUP = "/group/id/{groupId}/domain/{domainId}";
++    public String GET_GROUP = "/group/id/{groupId}/domain/{domainId}";
++
++    SharingRegistryEndpoints() throws ApplicationSettingsException {
++        BASE_URL = ServerSettings.getSharingRegistryServerHost() + ":" + ServerSettings.getSharingRegistryServerPort();
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/controllers/AccessController.java
index 0000000,0000000..238c8d0
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/controllers/AccessController.java
@@@ -1,0 -1,0 +1,71 @@@
++package org.apache.custos.sharing.service.api.controllers;
++
++import org.apache.custos.sharing.service.core.exceptions.SharingRegistryException;
++import org.apache.custos.sharing.service.core.service.SharingRegistryService;
++import org.springframework.beans.factory.annotation.Autowired;
++import org.springframework.http.HttpStatus;
++import org.springframework.http.ResponseEntity;
++import org.springframework.web.bind.annotation.*;
++
++import java.util.Collections;
++import java.util.List;
++import java.util.Map;
++
++@RestController
++public class AccessController {
++
++    @Autowired
++    SharingRegistryService sharingRegistryService;
++
++    /**
++     <p>API method to share an entity with users</p>
++     */
++    @RequestMapping(value = "share/users/domain/{domainId}/entity/{entityId}/permissionType/{permissionTypeId}/cascadePermission/{cascadePermission}", method = RequestMethod.PUT)
++    public ResponseEntity<String> shareEntityWithUsers(@RequestBody List<String> userList, @PathVariable("domainId") String domainId, @PathVariable("entityId") String entityId, @PathVariable("permissionType") String permissionTypeId, @PathVariable("cascadePermission") boolean cascadePermission){
++
++        boolean response = sharingRegistryService.shareEntityWithUsers(domainId, entityId, userList, permissionTypeId, cascadePermission);
++        if(response) return new ResponseEntity<>(HttpStatus.OK);
++        else throw new SharingRegistryException("Sharing entity with users failed");
++
++    }
++
++    /**
++     <p>API method to revoke sharing from a list of users</p>
++     */
++    @RequestMapping(value = "revoke/users/domain/{domainId}/entity/{entityId}/permissionType/{permissionTypeId}", method = RequestMethod.PUT)
++    public ResponseEntity<String> revokeEntitySharingFromUsers(@RequestBody List<String> userList, @PathVariable("domainId") String domainId, @PathVariable("entityId") String entityId, @PathVariable("permissionType") String permissionTypeId){
++        boolean response = sharingRegistryService.revokeEntitySharingFromUsers(domainId, entityId, userList, permissionTypeId);
++        if(response) return new ResponseEntity<>(HttpStatus.OK);
++        else throw new SharingRegistryException("Revoking entity sharing with users failed");
++    }
++
++    /**
++     <p>API method to share an entity with list of groups</p>
++     */
++    @RequestMapping(value = "share/groups/domain/{domainId}/entity/{entityId}/permissionType/{permissionTypeId}/cascadePermission/{cascadePermission}", method = RequestMethod.PUT)
++    public ResponseEntity<String> shareEntityWithGroups(@RequestBody List<String> groupList, @PathVariable("domainId") String domainId, @PathVariable("entityId") String entityId, @PathVariable("permissionType") String permissionTypeId, @PathVariable("cascadePermission") boolean cascadePermission){
++       boolean response = sharingRegistryService.shareEntityWithGroups(domainId,entityId, groupList, permissionTypeId, cascadePermission);
++        if(response) return new ResponseEntity<>(HttpStatus.OK);
++        else throw new SharingRegistryException("Sharing entity with groups failed");
++    }
++
++    /**
++     <p>API method to revoke sharing from list of users</p>
++     */
++    @RequestMapping(value = "revoke/groups/domain/{domainId}/entity/{entityId}/permissionType/{permissionTypeId}", method = RequestMethod.PUT)
++    public ResponseEntity<String> revokeEntitySharingFromGroups(@RequestBody List<String> groupList, @PathVariable("domainId") String domainId, @PathVariable("entityId") String entityId, @PathVariable("permissionType") String permissionTypeId){
++        boolean response = sharingRegistryService.revokeEntitySharingFromGroups(domainId, entityId, groupList, permissionTypeId);
++        if(response) return new ResponseEntity<>(HttpStatus.OK);
++        else throw new SharingRegistryException("Revoking entity sharing with groups failed");
++    }
++
++    /**
++     <p>API method to check whether a user has access to a specific entity</p>
++     */
++    @RequestMapping(value = "hasaccess/domain/{domainId}/user/{userId}/entity/{entityId}/permissionType/{permissionTypeId}", method = RequestMethod.PUT)
++    public @ResponseBody
++    Map<String, Boolean> userHasAccess(@PathVariable("domainId") String domainId, @PathVariable("userId") String userId, @PathVariable("entityId") String entityId, @PathVariable("permissionType") String permissionTypeId){
++        boolean response = sharingRegistryService.userHasAccess(domainId, userId, entityId, permissionTypeId);
++        return Collections.singletonMap("access", response);
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/controllers/DomainsController.java
index 0000000,0000000..ccfbd16
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/controllers/DomainsController.java
@@@ -1,0 -1,0 +1,79 @@@
++package org.apache.custos.sharing.service.api.controllers;
++
++import org.apache.custos.sharing.service.core.models.Domain;
++import org.apache.custos.sharing.service.core.exceptions.SharingRegistryException;
++import org.apache.custos.sharing.service.core.service.SharingRegistryService;
++import org.springframework.beans.factory.annotation.Autowired;
++import org.springframework.http.HttpStatus;
++import org.springframework.http.ResponseEntity;
++import org.springframework.web.bind.annotation.*;
++
++import java.util.Collections;
++import java.util.List;
++import java.util.Map;
++
++@RestController
++@RequestMapping("/domain")
++public class DomainsController {
++
++    @Autowired
++    private static SharingRegistryService sharingRegistryService;
++
++    /**
++     <p>API method to create a new domain</p>
++     */
++    @RequestMapping(value = "/create", method= RequestMethod.POST)
++    public ResponseEntity<String> createDomain(@RequestBody Domain domain){
++        String domainId = sharingRegistryService.createDomain(domain);
++        if(domainId.equals(domain.getDomainId())) return new ResponseEntity<>(HttpStatus.OK);
++        else throw new SharingRegistryException("Domain creation failed");
++    }
++
++    /**
++     <p>API method to update a domain</p>
++     */
++    @RequestMapping(value = "/update", method = RequestMethod.PUT)
++    public ResponseEntity<String> updateDomain(@RequestBody Domain domain){
++        boolean response = sharingRegistryService.updateDomain(domain);
++        if(response) return new ResponseEntity<>(HttpStatus.OK);
++        else throw new SharingRegistryException("Domain update failed");
++    }
++
++    /**
++     <p>API method to check Domain Exists</p>
++     */
++    @RequestMapping(value = "/exists/{domainId}", method = RequestMethod.GET)
++    public @ResponseBody
++    Map<String, Boolean> isDomainExists(@PathVariable("domainId") String domainId) {
++        boolean response = sharingRegistryService.isDomainExists(domainId);
++        return Collections.singletonMap("exists", response);
++    }
++
++    /**
++     <p>API method to retrieve a domain</p>
++     */
++    @RequestMapping(value = "/{domainId}",method = RequestMethod.GET)
++    public ResponseEntity<Domain> getDomain(@PathVariable("domainId") String domainId){
++        Domain domain = sharingRegistryService.getDomain(domainId);
++        if(domain != null) return new ResponseEntity<>(domain, HttpStatus.OK);
++        else return new ResponseEntity<>(HttpStatus.NOT_FOUND);
++    }
++
++    /**
++     <p>API method to delete domain</p>
++     */
++    @RequestMapping(value = "/{domainId}", method = RequestMethod.DELETE)
++    public @ResponseBody Map<String, Boolean> deleteDomain(@PathVariable("domainId") String domainId){
++        boolean response = sharingRegistryService.deleteDomain(domainId);
++        return Collections.singletonMap("success", response);
++    }
++
++    /**
++     <p>API method to get all domain.</p>
++     */
++    @RequestMapping(value = "/offset/{offset}/limit/{limit}", method = RequestMethod.GET)
++    public @ResponseBody List<Domain> getDomains(@PathVariable("offset") int offset, @PathVariable("limit") int limit){
++        return sharingRegistryService.getDomains(offset, limit);
++    }
++
++}
diff --cc custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/controllers/EntityController.java
index 0000000,0000000..60fdc6a
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/controllers/EntityController.java
@@@ -1,0 -1,0 +1,117 @@@
++package org.apache.custos.sharing.service.api.controllers;
++
++import org.apache.custos.sharing.service.core.models.Entity;
++import org.apache.custos.sharing.service.core.models.SearchCriteria;
++import org.apache.custos.sharing.service.core.models.User;
++import org.apache.custos.sharing.service.core.models.UserGroup;
++import org.apache.custos.sharing.service.core.exceptions.SharingRegistryException;
++import org.apache.custos.sharing.service.core.service.SharingRegistryService;
++import org.springframework.beans.factory.annotation.Autowired;
++import org.springframework.http.HttpStatus;
++import org.springframework.http.ResponseEntity;
++import org.springframework.web.bind.annotation.*;
++
++import java.util.Collections;
++import java.util.List;
++import java.util.Map;
++
++@RestController
++@RequestMapping("/entity")
++public class EntityController {
++
++    @Autowired
++    private SharingRegistryService sharingRegistryService;
++
++    /**
++     <p>API method to register new entity</p>
++     */
++    @RequestMapping(value = "/create", method = RequestMethod.POST)
++    public ResponseEntity<String> createEntity(@RequestBody Entity entity){
++        String createdEntityId = sharingRegistryService.createEntity(entity);
++        if(createdEntityId.equals(entity.getEntityId())){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }
++        else throw new SharingRegistryException("Failed to create the entity");
++    }
++
++    /**
++     <p>API method to update entity</p>
++     */
++    @RequestMapping(value = "/update", method = RequestMethod.PUT)
++    public ResponseEntity<String> updateEntity(@RequestBody Entity entity){
++        boolean response = sharingRegistryService.updateEntity(entity);
++        if(response) return new ResponseEntity<>(HttpStatus.OK);
++        else throw new SharingRegistryException("Failed to update the entity");
++    }
++
++    /**
++     <p>API method to check Entity Exists</p>
++     */
++    @RequestMapping(value = "/exists/id/{entityId}/domain/{domainId}", method = RequestMethod.GET)
++    public @ResponseBody Map<String, Boolean> isEntityExists(@PathVariable("entityId") String entityId, @PathVariable("domainId") String domainId){
++        boolean response = sharingRegistryService.isEntityExists(entityId, domainId);
++        return Collections.singletonMap("exists", response);
++    }
++
++    /**
++     <p>API method to delete entity</p>
++     */
++    @RequestMapping(value = "/id/{entityId}/domain/{domainId}", method = RequestMethod.DELETE)
++    public ResponseEntity<String> deleteEntity(@PathVariable("entityId") String entityId, @PathVariable("domainId") String domainId){
++        boolean response = sharingRegistryService.deleteEntity(domainId, entityId);
++        if(response) return new ResponseEntity<>(HttpStatus.OK);
++        else throw new SharingRegistryException("Could not delete the entity");
++    }
++
++    /**
++     <p>API method to get entity</p>
++     */
++    @RequestMapping(value = "/id/{entityId}/domain/{domainId}", method = RequestMethod.GET)
++    public @ResponseBody Entity getEntity(@PathVariable("entityId") String entityId, @PathVariable("domainId") String domainId){
++        Entity entity = sharingRegistryService.getEntity(domainId, entityId);
++        if(entity != null) return entity;
++        //TODO: not found exception should be thrown??
++        else throw new SharingRegistryException("Could not retrieve the entity");
++    }
++
++    /**
++     <p>API method to search entities</p>
++     */
++    @RequestMapping(value = "/search/domain/{domainId}/user/{userId}/offset/{offset}/limit/{limit}", method = RequestMethod.POST)
++    public @ResponseBody List<Entity> searchEntities(@RequestBody List<SearchCriteria> filters, @PathVariable("domainId") String domainId, @PathVariable("userId") String userId, @PathVariable("offset") int offset, @PathVariable("limit") int limit){
++        List<Entity> entities = sharingRegistryService.searchEntities(domainId, userId, filters, offset, limit);
++        return entities;
++    }
++
++    /**
++     <p>API method to get a list of shared users given the entity id</p>
++     */
++    @RequestMapping(value = "/sharedUsers/id/{entityId}/domain/{domainId}/permissionType/{permissionTypeId}", method = RequestMethod.GET)
++    public @ResponseBody List<User> getListOfSharedUsers(@PathVariable("entityId") String entityId, @PathVariable("domainId") String domainId, @PathVariable("permissionTypeId") String permissionTypeId){
++        return sharingRegistryService.getListOfSharedUsers(domainId, entityId, permissionTypeId);
++    }
++
++    /**
++     <p>API method to get a list of shared users given the entity id where the sharing type is directly applied</p>
++     */
++    @RequestMapping(value = "/directlySharedUsers/id/{entityId}/domain/{domainId}/permissionType/{permissionTypeId}", method = RequestMethod.GET)
++    public @ResponseBody List<User> getListOfDirectlySharedUsers(@PathVariable("entityId") String entityId, @PathVariable("domainId") String domainId, @PathVariable("permissionTypeId") String permissionTypeId){
++        return sharingRegistryService.getListOfDirectlySharedUsers(domainId, entityId, permissionTypeId);
++    }
++
++    /**
++     <p>API method to get a list of shared groups given the entity id</p>
++     */
++    @RequestMapping(value = "/sharedGroups/id/{entityId}/domain/{domainId}/permissionType/{permissionTypeId}", method = RequestMethod.GET)
++    public @ResponseBody List<UserGroup> getListOfSharedGroups(@PathVariable("entityId") String entityId, @PathVariable("domainId") String domainId, @PathVariable("permissionTypeId") String permissionTypeId){
++        return sharingRegistryService.getListOfSharedGroups(domainId, entityId, permissionTypeId);
++    }
++
++    /**
++     <p>API method to get a list of directly shared groups given the entity id where the sharing type is directly applied</p>
++     */
++    @RequestMapping(value = "/directlySharedGroups/id/{entityId}/domain/{domainId}/permissionType/{permissionTypeId}", method = RequestMethod.GET)
++    public @ResponseBody List<UserGroup> getListOfDirectlySharedGroups(@PathVariable("entityId") String entityId, @PathVariable("domainId") String domainId, @PathVariable("permissionTypeId") String permissionTypeId){
++        return sharingRegistryService.getListOfDirectlySharedGroups(domainId, entityId, permissionTypeId);
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/controllers/EntityTypeController.java
index 0000000,0000000..a806c38
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/controllers/EntityTypeController.java
@@@ -1,0 -1,0 +1,95 @@@
++package org.apache.custos.sharing.service.api.controllers;
++
++import org.apache.custos.sharing.service.core.models.EntityType;
++import org.apache.custos.sharing.service.core.exceptions.ResourceNotFoundException;
++import org.apache.custos.sharing.service.core.exceptions.SharingRegistryException;
++import org.apache.custos.sharing.service.core.service.SharingRegistryService;
++import org.springframework.beans.factory.annotation.Autowired;
++import org.springframework.http.HttpStatus;
++import org.springframework.http.ResponseEntity;
++import org.springframework.web.bind.annotation.*;
++
++import java.util.Collections;
++import java.util.List;
++import java.util.Map;
++
++@RestController
++@RequestMapping("/entityType")
++public class EntityTypeController {
++
++    @Autowired
++    private static SharingRegistryService sharingRegistryService;
++    /**
++     <p>API method to create a new entity type</p>
++     */
++    @RequestMapping(value = "/create", method = RequestMethod.POST)
++    public ResponseEntity<String> createEntityType(@RequestBody EntityType entityType){
++        String createdEntityTypeId = sharingRegistryService.createEntityType(entityType);
++        if(createdEntityTypeId.equals(entityType.getEntityTypeId())){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }
++        else{
++            throw new SharingRegistryException("Failed to create the entity type");
++        }
++    }
++
++    /**
++     <p>API method to update entity type</p>
++     */
++    @RequestMapping(value = "/update", method = RequestMethod.PUT)
++    public ResponseEntity<String> updateEntityType(@RequestBody EntityType entityType){
++        boolean response = sharingRegistryService.updateEntityType(entityType);
++        if(response){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }
++        else{
++            throw new SharingRegistryException("Failed to updated the entity type");
++        }
++    }
++
++    /**
++     <p>API method to check EntityType Exists</p>
++     */
++    @RequestMapping(value = "/exists/id/{entityTypeId/domain/{domainId}", method = RequestMethod.GET)
++    public @ResponseBody Map<String, Boolean> isEntityTypeExists(@PathVariable("entityTypeId") String entityTypeId, @PathVariable("domainId") String domainId){
++        boolean response = sharingRegistryService.isEntityTypeExists(domainId, entityTypeId);
++        return Collections.singletonMap("exists", response);
++    }
++
++    /**
++     <p>API method to delete entity type</p>
++     */
++    @RequestMapping(value = "/id/{entityTypeId}/domain/{domainId}", method = RequestMethod.DELETE)
++    public ResponseEntity<String> deleteEntityType(@PathVariable("entityTypeId") String entityTypeId, @PathVariable("domainId") String domainId){
++        boolean response = sharingRegistryService.deleteEntityType(domainId, entityTypeId);
++        if(response){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }
++        else{
++            throw new SharingRegistryException("Failed to delete the entity type");
++        }
++    }
++
++    /**
++     <p>API method to get an entity type</p>
++     */
++    @RequestMapping(value = "/id/{entityTypeId}/domain/{domainId}", method = RequestMethod.GET)
++    public @ResponseBody EntityType getEntityType(@PathVariable("entityTypeId") String entityTypeId, @PathVariable("domainId") String domainId){
++        EntityType entityType = sharingRegistryService.getEntityType(domainId, entityTypeId);
++        if(entityType != null){
++            return entityType;
++        }
++        else{
++            throw new ResourceNotFoundException("Could not find the entity type with entityTypeId: " + entityTypeId + " in domainId: "+ domainId);
++        }
++    }
++
++    /**
++     <p>API method to get entity types in a domainId.</p>
++     */
++    @RequestMapping(value = "/domain/{domainId}/offset/{offset}/limit/{limit}", method = RequestMethod.GET)
++    public @ResponseBody List<EntityType> getEntityTypes(@PathVariable("domainId") String domainId, @PathVariable("offset") int offset, @PathVariable("limit") int limit){
++       List<EntityType> entityTypes = sharingRegistryService.getEntityTypes(domainId, offset, limit);
++       return entityTypes;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/controllers/GroupController.java
index 0000000,0000000..0c1eced
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/controllers/GroupController.java
@@@ -1,0 -1,0 +1,244 @@@
++package org.apache.custos.sharing.service.api.controllers;
++
++import org.apache.custos.sharing.service.core.models.GroupAdmin;
++import org.apache.custos.sharing.service.core.models.User;
++import org.apache.custos.sharing.service.core.models.UserGroup;
++import org.apache.custos.sharing.service.core.exceptions.ResourceNotFoundException;
++import org.apache.custos.sharing.service.core.exceptions.SharingRegistryException;
++import org.apache.custos.sharing.service.core.service.SharingRegistryService;
++import org.springframework.beans.factory.annotation.Autowired;
++import org.springframework.http.HttpStatus;
++import org.springframework.http.ResponseEntity;
++import org.springframework.web.bind.annotation.*;
++
++import java.util.Collections;
++import java.util.List;
++import java.util.Map;
++
++@RestController
++public class GroupController {
++
++    @Autowired
++    private static SharingRegistryService sharingRegistryService;
++
++    /**
++     <p>API method to create a new group</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups", method = RequestMethod.POST)
++    public ResponseEntity<String> createGroup(@RequestBody UserGroup group){
++        String createdGroupId = sharingRegistryService.createGroup(group);
++        if(createdGroupId.equals(group.getGroupId())){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }else{
++            throw new SharingRegistryException("Failed to create group");
++        }
++    }
++
++    /**
++     <p>API method to update a group</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups", method = RequestMethod.PUT)
++    public ResponseEntity<String> updateGroup(@RequestBody UserGroup group){
++        boolean response = sharingRegistryService.updateGroup(group);
++        if(response){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }
++        else{
++            throw new SharingRegistryException("Failed to update the group");
++        }
++    }
++
++    /**
++     <p>API method to check Group Exists</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups/{groupId}", method = RequestMethod.HEAD)
++    public ResponseEntity<String> isGroupExists(@PathVariable("domainId") String domainId, @PathVariable("groupId") String groupId){
++        boolean response = sharingRegistryService.isGroupExists(domainId, groupId);
++        HttpStatus status = HttpStatus.NOT_FOUND;
++        if(response){
++            status = HttpStatus.OK;
++        }
++        return new ResponseEntity<>(status);
++    }
++
++    /**
++     <p>API method to delete a group</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups/{groupId}", method = RequestMethod.DELETE)
++    public ResponseEntity<String> deleteGroup(@PathVariable("domainId") String domainId, @PathVariable("groupId") String groupId){
++        boolean response = sharingRegistryService.deleteGroup(domainId, groupId);
++        if(response){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }
++        else{
++            throw new SharingRegistryException("Failed to delete the group");
++        }
++    }
++
++    /**
++     <p>API method to get a group</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups/{groupId}", method = RequestMethod.GET)
++    public @ResponseBody UserGroup getGroup(@PathVariable("groupId") String groupId, @PathVariable("domainId") String domainId){
++        UserGroup userGroup = sharingRegistryService.getGroup(domainId,groupId);
++        if(userGroup != null){
++            return userGroup;
++        }else{
++            throw new ResourceNotFoundException("Could not find the user group with groupId: "+ groupId + " in domainId: "+ domainId);
++        }
++    }
++
++    /**
++     <p>API method to get groups in a domainId.</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups",method = RequestMethod.GET)
++    public @ResponseBody List<UserGroup> getGroups(@PathVariable("domainId") String domainId, @RequestParam int offset, @RequestParam int limit){
++        return sharingRegistryService.getGroups(domainId, offset, limit);
++    }
++
++    /**
++     <p>API method to add list of users to a group</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups/{groupId}/users", method = RequestMethod.POST)
++    public ResponseEntity<String> addUsersToGroup(@PathVariable("groupId") String groupId, @PathVariable("domainId") String domainId, @RequestBody List<String> userIds){
++        boolean response = sharingRegistryService.addUsersToGroup(domainId, userIds, groupId);
++        if(response){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }
++        else{
++            throw new SharingRegistryException("Failed to add users to the group");
++        }
++    }
++
++    /**
++     <p>API method to remove users from a group</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups/{groupId}/users", method = RequestMethod.DELETE)
++    public ResponseEntity<String> removeUsersFromGroup(@PathVariable("groupId") String groupId, @PathVariable("domainId") String domainId, @RequestBody List<String> userIds){
++        boolean response = sharingRegistryService.removeUsersFromGroup(domainId, userIds, groupId);
++        if(response){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }
++        else{
++            throw new SharingRegistryException("Failed to remove users from the group");
++        }
++    }
++
++    /**
++     <p>API method to transfer group ownership</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups/{groupId}/owners/{ownerId}", method = RequestMethod.PUT)
++    public ResponseEntity<String> transferGroupOwnership(@PathVariable("domainId") String domainId,@PathVariable("groupId") String groupId, @PathVariable("ownerId") String newOwnerId){
++        boolean response = sharingRegistryService.transferGroupOwnership(domainId,groupId, newOwnerId);
++        if(response){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }
++        else{
++            throw new SharingRegistryException("Failed to change group owner");
++        }
++    }
++
++    /**
++     <p>API method to add Admin for a group</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups/{groupId}/admins", method = RequestMethod.POST)
++    public ResponseEntity<String> addGroupAdmins(@PathVariable("domainId") String domainId,@PathVariable("groupId") String groupId, @RequestBody List<GroupAdmin> admins){
++        boolean response = sharingRegistryService.addGroupAdmins(domainId,groupId, admins);
++        if(response){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }
++        else{
++            throw new SharingRegistryException("Failed to add group admins");
++        }
++    }
++
++    /**
++     <p>API method to remove Admin for a group</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups/{groupId}/admins", method = RequestMethod.DELETE)
++    public ResponseEntity<String> removeGroupAdmins(@PathVariable("domainId") String domainId,@PathVariable("groupId") String groupId, @RequestBody List<String> adminIds){
++        boolean response = sharingRegistryService.removeGroupAdmins(domainId,groupId, adminIds);
++        if(response){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }
++        else{
++            throw new SharingRegistryException("Failed to remove group admins");
++        }
++    }
++
++    /**
++     <p>API method to check whether the user has Admin access for the group</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups/{groupId}/admin/{adminId}", method = RequestMethod.HEAD)
++    public ResponseEntity<String> hasAdminAccess(@PathVariable("domainId") String domainId, @PathVariable("groupId") String groupId, @PathVariable("adminId") String adminId){
++        boolean response = sharingRegistryService.hasAdminAccess(domainId, groupId, adminId);
++        HttpStatus status = HttpStatus.NOT_FOUND;
++        if(response){
++            status = HttpStatus.OK;
++        }
++        return new ResponseEntity<>(status);
++    }
++
++    /**
++     <p>API method to check whether the user has Owner access for the group</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups/{groupId}/owner/{ownerId}", method = RequestMethod.HEAD)
++    public ResponseEntity<String> hasOwnerAccess(@PathVariable("domainId") String domainId, @PathVariable("groupId") String groupId, @PathVariable("ownerId") String ownerId){
++        boolean response = sharingRegistryService.hasOwnerAccess(domainId, groupId, ownerId);
++        HttpStatus status = HttpStatus.NOT_FOUND;
++        if(response){
++            status = HttpStatus.OK;
++        }
++        return new ResponseEntity<>(status);
++    }
++
++    /**
++     <p>API method to get list of child users in a group. Only the direct members will be returned.</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups/{groupId}/users", method = RequestMethod.GET)
++    public List<User> getGroupMembersOfTypeUser(@PathVariable("domainId") String domainId, @PathVariable("groupId") String groupId, @RequestParam("offset") int offset, @RequestParam("limit") int limit){
++        return sharingRegistryService.getGroupMembersOfTypeUser(domainId, groupId, offset, limit);
++    }
++
++    /**
++     <p>API method to get list of child groups in a group. Only the direct members will be returned.</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups/{groupId}/subgroups", method = RequestMethod.GET)
++    public List<UserGroup> getGroupMembersOfTypeGroup(@PathVariable("domainId") String domainId, @PathVariable("groupId") String groupId, @RequestParam("offset") int offset, @RequestParam("limit") int limit){
++        return sharingRegistryService.getGroupMembersOfTypeGroup(domainId, groupId, offset, limit);
++    }
++
++    /**
++     <p>API method to add a child group to a parent group.</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups/{groupId}/subgroups", method = RequestMethod.POST)
++    public ResponseEntity<String> addChildGroupsToParentGroup(@PathVariable("domainId") String domainId, @PathVariable("groupId") String groupId, @RequestBody List<String> childIds){
++        boolean response = sharingRegistryService.addChildGroupsToParentGroup(domainId, childIds, groupId);
++        if(response){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }else{
++            throw new SharingRegistryException("Failed to add child groups to parent group");
++        }
++    }
++
++    /**
++     <p>API method to remove a child group from parent group.</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/groups/{groupId}/subgroups", method = RequestMethod.DELETE)
++    public ResponseEntity<String> removeChildGroupFromParentGroup(@PathVariable("domainId") String domainId, @PathVariable("groupId") String groupId, @PathVariable("childGroupId") String childGroupId){
++        boolean response = sharingRegistryService.removeChildGroupFromParentGroup(domainId, childGroupId, groupId);
++        if(response){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }else{
++            throw new SharingRegistryException("Failed to remove child groups from parent group");
++        }
++    }
++
++    /**
++     <p>API method to get all groups user is a member of.</p>
++     */
++    @RequestMapping(value = "/domains/{domainId}/users/{userId}/groups", method = RequestMethod.PUT)
++    public @ResponseBody List<UserGroup> getAllMemberGroupsForUser(@PathVariable("domainId") String domainId, @PathVariable("userId") String userId){
++        return sharingRegistryService.getAllMemberGroupsForUser(domainId, userId);
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/controllers/PermissionTypeController.java
index 0000000,0000000..cfcf567
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/controllers/PermissionTypeController.java
@@@ -1,0 -1,0 +1,94 @@@
++package org.apache.custos.sharing.service.api.controllers;
++
++import org.apache.custos.sharing.service.core.models.PermissionType;
++import org.apache.custos.sharing.service.core.exceptions.ResourceNotFoundException;
++import org.apache.custos.sharing.service.core.exceptions.SharingRegistryException;
++import org.apache.custos.sharing.service.core.service.SharingRegistryService;
++import org.springframework.beans.factory.annotation.Autowired;
++import org.springframework.http.HttpStatus;
++import org.springframework.http.ResponseEntity;
++import org.springframework.web.bind.annotation.*;
++
++import java.util.Collections;
++import java.util.List;
++import java.util.Map;
++
++@RestController
++@RequestMapping("/permissionType")
++public class PermissionTypeController {
++
++    @Autowired
++    private static SharingRegistryService sharingRegistryService;
++    /**
++     <p>API method to create permission type</p>
++     */
++    @RequestMapping(value= "/create", method = RequestMethod.POST)
++    public ResponseEntity<String> createPermissionType(@RequestBody PermissionType permissionType){
++        String permissionTypeId = sharingRegistryService.createPermissionType(permissionType);
++        if(permissionTypeId.equals(permissionType.getPermissionTypeId())){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }else{
++            throw new SharingRegistryException("Could not create the permission type");
++        }
++    }
++
++    /**
++     <p>API method to update permission type</p>
++     */
++    @RequestMapping(value= "/update", method = RequestMethod.PUT)
++    public ResponseEntity<String> updatePermissionType(@RequestBody PermissionType permissionType){
++
++        boolean response = sharingRegistryService.updatePermissionType(permissionType);
++        if(response){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }else{
++            throw new SharingRegistryException("Could not update the permission type");
++        }
++    }
++
++    /**
++     <p>API method to check Permission Exists</p>
++     */
++    @RequestMapping(value= "/exists/id/{permissionId}/domain/{domainId}", method = RequestMethod.GET)
++    public @ResponseBody
++    Map<String, Boolean> isPermissionExists(@PathVariable("permissionId") String permissionId, @PathVariable("domainId") String domainId){
++        boolean response = sharingRegistryService.isPermissionExists(domainId, permissionId);
++        return Collections.singletonMap("exists", response);
++    }
++
++    /**
++     <p>API method to delete permission type</p>
++     */
++    @RequestMapping(value= "/id/{permissionTypeId}/domain/{domainId}", method = RequestMethod.DELETE)
++    public ResponseEntity<String> deletePermissionType(@PathVariable("permissionTypeId") String permissionTypeId, @PathVariable("domainId") String domainId){
++        boolean response = sharingRegistryService.deletePermissionType(domainId,permissionTypeId);
++        if(response){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }else{
++            throw new SharingRegistryException("Could not delete the permission type");
++        }
++    }
++
++    /**
++     <p>API method to get permission type</p>
++     */
++    @RequestMapping(value= "/id/{permissionTypeId}/domain/{domainId}", method = RequestMethod.GET)
++    public @ResponseBody PermissionType getPermissionType(@PathVariable("permissionTypeId") String permissionTypeId, @PathVariable("domainId") String domainId){
++        PermissionType permissionType = sharingRegistryService.getPermissionType(domainId, permissionTypeId);
++        if(permissionType != null){
++            return permissionType;
++        }else{
++            throw new ResourceNotFoundException("Could not find the permission type with permission Id: "+ permissionTypeId + " in domainId: " + domainId);
++        }
++    }
++
++    /**
++     <p>API method to get list of permission types in a given domainId.</p>
++     */
++    @RequestMapping(value= "/domain/{domainId}/offset/{offset}/limit/{limit}", method = RequestMethod.GET)
++    public @ResponseBody
++    List<PermissionType> getPermissionTypes(@PathVariable("domainId") String domainId, @PathVariable("offset") int offset, @PathVariable("limit") int limit){
++        return sharingRegistryService.getPermissionTypes(domainId, offset, limit);
++    }
++
++}
diff --cc custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/controllers/UsersController.java
index 0000000,0000000..00ef0a4
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-api/src/main/java/org/apache/custos/sharing/service/api/controllers/UsersController.java
@@@ -1,0 -1,0 +1,95 @@@
++package org.apache.custos.sharing.service.api.controllers;
++
++import org.apache.custos.sharing.service.core.models.User;
++import org.apache.custos.sharing.service.core.exceptions.ResourceNotFoundException;
++import org.apache.custos.sharing.service.core.exceptions.SharingRegistryException;
++import org.apache.custos.sharing.service.core.service.SharingRegistryService;
++import org.springframework.beans.factory.annotation.Autowired;
++import org.springframework.http.HttpStatus;
++import org.springframework.http.ResponseEntity;
++import org.springframework.web.bind.annotation.*;
++
++import java.util.Collections;
++import java.util.List;
++import java.util.Map;
++
++@RestController
++@RequestMapping("/user")
++public class UsersController {
++
++    @Autowired
++    private static SharingRegistryService sharingRegistryService;
++
++    /**
++     <p>API method to register a user in the system</p>
++     */
++    @RequestMapping(method = RequestMethod.POST)
++    public ResponseEntity<String> createUser(@RequestBody User user){
++        String userId = sharingRegistryService.createUser(user);
++        if(userId.equals(user.getUserId())){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }else{
++            throw new SharingRegistryException("Failed to create the user");
++        }
++    }
++
++    /**
++     <p>API method to update existing user</p>
++     */
++    @RequestMapping(method = RequestMethod.PUT)
++    public ResponseEntity<String> updateUser(@RequestBody User user){
++        boolean response = sharingRegistryService.updatedUser(user);
++        if(response){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }else{
++            throw new SharingRegistryException("Failed to update the user");
++        }
++    }
++
++    /**
++     <p>API method to check User Exists</p>
++     */
++    @RequestMapping(value = "/exists/domainId/{domainId}/userId/{userId}", method = RequestMethod.GET)
++    public @ResponseBody
++    Map<String, Boolean> isUserExists(@PathVariable("domainId") String domainId, @PathVariable("userId") String userId){
++        boolean response = sharingRegistryService.isUserExists(domainId, userId);
++        return Collections.singletonMap("exists", response);
++    }
++
++    /**
++     <p>API method to delete user</p>
++     */
++    @RequestMapping(value="/id/{userId}/domain/{domainId}",method = RequestMethod.DELETE)
++    public ResponseEntity<String> deleteUser(@PathVariable("userId") String userId, @PathVariable("domainId") String domainId){
++        boolean response = sharingRegistryService.deleteUser(domainId, userId);
++        if(response){
++            return new ResponseEntity<>(HttpStatus.OK);
++        }else{
++            throw new SharingRegistryException("Failed to delete the user");
++        }
++    }
++
++    /**
++     <p>API method to get a user</p>
++     */
++    @RequestMapping(value = "/domain/{domainId}/user/{userId}", method = RequestMethod.GET)
++    public User getUser(@PathVariable("domainId") String domainId,@PathVariable("userId") String userId){
++        User user = sharingRegistryService.getUser(domainId, userId);
++        if(user != null){
++            return user;
++        }else {
++            throw new ResourceNotFoundException("Could not find the user with userId: "+ userId + " for domainId: "+ domainId);
++        }
++    }
++
++    /**
++     <p>API method to get a list of users in a specific domain.</p>
++     <li>domainId : Domain id</li>
++     <li>offset : Starting result number</li>
++     <li>limit : Number of max results to be sent</li>
++     */
++    @RequestMapping(value = "/domainId/{domainId}/offset/{offset}/limit/{limit}")
++    public List<User> getUsers(@PathVariable("domainId") String domainId, @PathVariable("offset") int offset, @PathVariable("limit") int limit){
++        return sharingRegistryService.getUsers(domainId,offset, limit);
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/pom.xml
index 0000000,0000000..7922b89
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/pom.xml
@@@ -1,0 -1,0 +1,58 @@@
++<?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-sharing-registry-service</artifactId>
++        <groupId>org.apache.custos</groupId>
++        <version>1.0-SNAPSHOT</version>
++    </parent>
++    <modelVersion>4.0.0</modelVersion>
++
++    <artifactId>sharing-service-core</artifactId>
++    <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.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>junit</groupId>
++            <artifactId>junit</artifactId>
++            <version>${junit.version}</version>
++            <scope>test</scope>
++        </dependency>
++    </dependencies>
++
++</project>
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/DomainEntity.java
index 0000000,0000000..ad960a5
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/DomainEntity.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/EntityEntity.java
index 0000000,0000000..9340c43
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/EntityEntity.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/EntityPK.java
index 0000000,0000000..f3badf0
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/EntityPK.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/EntityTypeEntity.java
index 0000000,0000000..8412e9c
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/EntityTypeEntity.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/EntityTypePK.java
index 0000000,0000000..bf92438
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/EntityTypePK.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/GroupAdminEntity.java
index 0000000,0000000..cc0e1c7
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/GroupAdminEntity.java
@@@ -1,0 -1,0 +1,80 @@@
++package org.apache.custos.sharing.service.core.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 --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/GroupAdminPK.java
index 0000000,0000000..73e8ea2
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/GroupAdminPK.java
@@@ -1,0 -1,0 +1,66 @@@
++package org.apache.custos.sharing.service.core.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 --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/GroupMembershipEntity.java
index 0000000,0000000..a25b5d4
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/GroupMembershipEntity.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/GroupMembershipPK.java
index 0000000,0000000..08a5e4f
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/GroupMembershipPK.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/PermissionTypeEntity.java
index 0000000,0000000..9c8dfb3
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/PermissionTypeEntity.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/PermissionTypePK.java
index 0000000,0000000..1d3dda3
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/PermissionTypePK.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/SharingEntity.java
index 0000000,0000000..a48364b
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/SharingEntity.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/SharingPK.java
index 0000000,0000000..85764bd
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/SharingPK.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/UserEntity.java
index 0000000,0000000..fea6250
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/UserEntity.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/UserGroupEntity.java
index 0000000,0000000..d3fe9bb
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/UserGroupEntity.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/UserGroupPK.java
index 0000000,0000000..4395b1d
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/UserGroupPK.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/UserPK.java
index 0000000,0000000..a7c7090
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/entities/UserPK.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/AbstractRepository.java
index 0000000,0000000..c70998b
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/AbstractRepository.java
@@@ -1,0 -1,0 +1,169 @@@
++/**
++ *
++ * 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.service.core.db.repositories;
++
++
++import org.apache.custos.sharing.service.core.db.utils.Committer;
++import org.apache.custos.sharing.service.core.db.utils.DBConstants;
++import org.apache.custos.sharing.service.core.db.utils.JPAUtils;
++import org.apache.custos.sharing.service.core.db.utils.ObjectMapperSingleton;
++import org.apache.custos.sharing.service.core.exceptions.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> genericClass;
++    private Class<E> dbEntityGenericClass;
++
++    public AbstractRepository(Class<T> genericClass, Class<E> dbEntityGenericClass){
++        this.genericClass = genericClass;
++        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, genericClass);
++    }
++
++    //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, genericClass);
++    }
++
++    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, genericClass)));
++        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, genericClass)));
++        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();
++            }
++        }
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/DomainRepository.java
index 0000000,0000000..6db47bb
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/DomainRepository.java
@@@ -1,0 -1,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.service.core.db.repositories;
++
++import org.apache.custos.sharing.service.core.db.entities.DomainEntity;
++import org.apache.custos.sharing.service.core.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);
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/EntityRepository.java
index 0000000,0000000..2f16f60
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/EntityRepository.java
@@@ -1,0 -1,0 +1,180 @@@
++/**
++ *
++ * 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.service.core.db.repositories;
++
++import org.apache.custos.sharing.service.core.db.entities.EntityEntity;
++import org.apache.custos.sharing.service.core.db.entities.EntityPK;
++import org.apache.custos.sharing.service.core.db.utils.DBConstants;
++import org.apache.custos.sharing.service.core.db.utils.SharingRegistryJDBCConfig;
++import org.apache.custos.sharing.service.core.exceptions.SharingRegistryException;
++import org.apache.custos.sharing.service.core.models.Entity;
++import org.apache.custos.sharing.service.core.models.EntitySearchField;
++import org.apache.custos.sharing.service.core.models.SearchCondition;
++import org.apache.custos.sharing.service.core.models.SearchCriteria;
++
++import java.util.ArrayList;
++import java.util.HashMap;
++import java.util.List;
++import java.util.Map;
++
++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 --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/EntityTypeRepository.java
index 0000000,0000000..0512f12
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/EntityTypeRepository.java
@@@ -1,0 -1,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.service.core.db.repositories;
++
++import org.apache.custos.sharing.service.core.db.entities.EntityTypeEntity;
++import org.apache.custos.sharing.service.core.db.entities.EntityTypePK;
++import org.apache.custos.sharing.service.core.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);
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/GroupAdminRepository.java
index 0000000,0000000..643378f
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/GroupAdminRepository.java
@@@ -1,0 -1,0 +1,17 @@@
++package org.apache.custos.sharing.service.core.db.repositories;
++
++import org.apache.custos.sharing.service.core.models.GroupAdmin;
++import org.apache.custos.sharing.service.core.db.entities.GroupAdminEntity;
++import org.apache.custos.sharing.service.core.db.entities.GroupAdminPK;
++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 --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/GroupMembershipRepository.java
index 0000000,0000000..b3cf11d
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/GroupMembershipRepository.java
@@@ -1,0 -1,0 +1,105 @@@
++/**
++ *
++ * 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.service.core.db.repositories;
++
++import org.apache.custos.sharing.service.core.models.*;
++import org.apache.custos.sharing.service.core.db.entities.GroupMembershipEntity;
++import org.apache.custos.sharing.service.core.db.entities.GroupMembershipPK;
++import org.apache.custos.sharing.service.core.db.entities.UserEntity;
++import org.apache.custos.sharing.service.core.db.entities.UserGroupEntity;
++import org.apache.custos.sharing.service.core.db.utils.DBConstants;
++import org.apache.custos.sharing.service.core.exceptions.SharingRegistryException;
++
++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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/PermissionTypeRepository.java
index 0000000,0000000..d5a650e
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/PermissionTypeRepository.java
@@@ -1,0 -1,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.service.core.db.repositories;
++
++import org.apache.custos.sharing.service.core.models.PermissionType;
++import org.apache.custos.sharing.service.core.db.entities.PermissionTypeEntity;
++import org.apache.custos.sharing.service.core.db.entities.PermissionTypePK;
++import org.apache.custos.sharing.service.core.db.utils.DBConstants;
++import org.apache.custos.sharing.service.core.exceptions.SharingRegistryException;
++import org.apache.custos.sharing.service.core.service.SharingRegistryService;
++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, SharingRegistryService.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 " + SharingRegistryService.OWNER_PERMISSION_NAME + " name");
++        }
++        return permissionTypeList.get(0).getPermissionTypeId();
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/SharingRepository.java
index 0000000,0000000..bd32d25
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/SharingRepository.java
@@@ -1,0 -1,0 +1,114 @@@
++/**
++ *
++ * 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.service.core.db.repositories;
++
++import org.apache.custos.sharing.service.core.models.Sharing;
++import org.apache.custos.sharing.service.core.models.SharingType;
++import org.apache.custos.sharing.service.core.db.entities.SharingEntity;
++import org.apache.custos.sharing.service.core.db.entities.SharingPK;
++import org.apache.custos.sharing.service.core.db.utils.DBConstants;
++import org.apache.custos.sharing.service.core.exceptions.SharingRegistryException;
++import org.slf4j.Logger;
++import org.slf4j.LoggerFactory;
++
++import javax.persistence.Query;
++import java.util.HashMap;
++import java.util.List;
++import java.util.Map;
++
++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 --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/UserGroupRepository.java
index 0000000,0000000..a581df4
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/UserGroupRepository.java
@@@ -1,0 -1,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.service.core.db.repositories;
++
++import org.apache.custos.sharing.service.core.models.GroupCardinality;
++import org.apache.custos.sharing.service.core.models.SharingType;
++import org.apache.custos.sharing.service.core.models.UserGroup;
++import org.apache.custos.sharing.service.core.db.entities.SharingEntity;
++import org.apache.custos.sharing.service.core.db.entities.UserGroupEntity;
++import org.apache.custos.sharing.service.core.db.entities.UserGroupPK;
++import org.apache.custos.sharing.service.core.db.utils.DBConstants;
++import org.apache.custos.sharing.service.core.exceptions.SharingRegistryException;
++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 --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/UserRepository.java
index 0000000,0000000..f4ff512
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/repositories/UserRepository.java
@@@ -1,0 -1,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.service.core.db.repositories;
++
++import org.apache.custos.sharing.service.core.db.entities.SharingEntity;
++import org.apache.custos.sharing.service.core.db.entities.UserEntity;
++import org.apache.custos.sharing.service.core.db.entities.UserPK;
++import org.apache.custos.sharing.service.core.db.utils.DBConstants;
++import org.apache.custos.sharing.service.core.exceptions.SharingRegistryException;
++import org.apache.custos.sharing.service.core.models.SharingType;
++import org.apache.custos.sharing.service.core.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 --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/utils/Committer.java
index 0000000,0000000..0f20997
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/utils/Committer.java
@@@ -1,0 -1,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.service.core.db.utils;
++
++@FunctionalInterface
++public interface Committer<T, R>  {
++
++    R commit(T t);
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/utils/DBConstants.java
index 0000000,0000000..d57c5c8
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/utils/DBConstants.java
@@@ -1,0 -1,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.service.core.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";
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/utils/JPAUtils.java
index 0000000,0000000..6640c46
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/utils/JPAUtils.java
@@@ -1,0 -1,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.service.core.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 --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/utils/ObjectMapperSingleton.java
index 0000000,0000000..2cbade7
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/utils/ObjectMapperSingleton.java
@@@ -1,0 -1,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.service.core.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;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/utils/SharingRegistryDBInitConfig.java
index 0000000,0000000..44cf9a5
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/utils/SharingRegistryDBInitConfig.java
@@@ -1,0 -1,0 +1,50 @@@
++/*
++ * 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.service.core.db.utils;
++
++
++import org.apache.custos.commons.utils.DBInitConfig;
++import org.apache.custos.commons.utils.JDBCConfig;
++import org.springframework.stereotype.Component;
++
++@Component
++public class SharingRegistryDBInitConfig implements DBInitConfig {
++    //TODO: check if this field should be read from configuration file
++    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 --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/utils/SharingRegistryJDBCConfig.java
index 0000000,0000000..8bfa5ec
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/db/utils/SharingRegistryJDBCConfig.java
@@@ -1,0 -1,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.service.core.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 --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/exceptions/DuplicateEntryException.java
index 0000000,0000000..8f79a0c
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/exceptions/DuplicateEntryException.java
@@@ -1,0 -1,0 +1,15 @@@
++package org.apache.custos.sharing.service.core.exceptions;
++
++import org.springframework.http.HttpStatus;
++import org.springframework.web.bind.annotation.ResponseStatus;
++
++@ResponseStatus(value= HttpStatus.CONFLICT, reason = "Request cannot be completed because a duplicate entry is requested")
++public class DuplicateEntryException extends RuntimeException {
++
++    public DuplicateEntryException(String errorMessage, Throwable err) {
++        super(errorMessage, err);
++    }
++    public DuplicateEntryException(String errorMessage) {
++        super(errorMessage);
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/exceptions/ResourceNotFoundException.java
index 0000000,0000000..df5dbbb
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/exceptions/ResourceNotFoundException.java
@@@ -1,0 -1,0 +1,16 @@@
++package org.apache.custos.sharing.service.core.exceptions;
++
++import org.springframework.http.HttpStatus;
++import org.springframework.web.bind.annotation.ResponseStatus;
++
++@ResponseStatus(value= HttpStatus.NOT_FOUND, reason = "Request cannot be completed because the server could not find the resource")
++public class ResourceNotFoundException extends RuntimeException{
++
++    public ResourceNotFoundException(String errorMessage) {
++        super(errorMessage);
++    }
++
++    public ResourceNotFoundException(String errorMessage, Throwable err) {
++        super(errorMessage, err);
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/exceptions/SharingRegistryException.java
index 0000000,0000000..a38ee8c
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/exceptions/SharingRegistryException.java
@@@ -1,0 -1,0 +1,16 @@@
++package org.apache.custos.sharing.service.core.exceptions;
++
++import org.springframework.http.HttpStatus;
++import org.springframework.web.bind.annotation.ResponseStatus;
++
++@ResponseStatus(value= HttpStatus.INTERNAL_SERVER_ERROR, reason = "Request cannot be completed due to server error")
++public class SharingRegistryException extends RuntimeException {
++
++    public SharingRegistryException(String errorMessage) {
++        super(errorMessage);
++    }
++
++    public SharingRegistryException(String errorMessage, Throwable err) {
++        super(errorMessage, err);
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/Domain.java
index 0000000,0000000..b7f8733
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/Domain.java
@@@ -1,0 -1,0 +1,49 @@@
++package org.apache.custos.sharing.service.core.models;
++
++public class Domain {
++    private String domainId = "DO_NOT_SET_AT_CLIENTS_ID";
++    private String name;
++    private String description;
++    private double createdTime;
++    private double updatedTime;
++
++    public String getDomainId() {
++        return domainId;
++    }
++
++    public void setDomainId(String domainId) {
++        this.domainId = domainId;
++    }
++
++    public String getName() {
++        return name;
++    }
++
++    public void setName(String name) {
++        this.name = name;
++    }
++
++    public String getDescription() {
++        return description;
++    }
++
++    public void setDescription(String description) {
++        this.description = description;
++    }
++
++    public double getCreatedTime() {
++        return createdTime;
++    }
++
++    public void setCreatedTime(double createdTime) {
++        this.createdTime = createdTime;
++    }
++
++    public double getUpdatedTime() {
++        return updatedTime;
++    }
++
++    public void setUpdatedTime(double updatedTime) {
++        this.updatedTime = updatedTime;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/Entity.java
index 0000000,0000000..0410130
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/Entity.java
@@@ -1,0 -1,0 +1,121 @@@
++package org.apache.custos.sharing.service.core.models;
++
++public class Entity {
++    private String entityId;
++    private String domainId;
++    private String entityTypeId;
++    private String ownerId;
++    private String parentEntityId;
++    private String name;
++    private String description;
++    private byte[] binaryData;
++    private String fullText;
++    private double sharedCount = 0;
++    private double originalEntityCreationTime;
++    private double createdTime;
++    private double updatedTime;
++
++    public String getEntityId() {
++        return entityId;
++    }
++
++    public void setEntityId(String entityId) {
++        this.entityId = entityId;
++    }
++
++    public String getDomainId() {
++        return domainId;
++    }
++
++    public void setDomainId(String domainId) {
++        this.domainId = domainId;
++    }
++
++    public String getEntityTypeId() {
++        return entityTypeId;
++    }
++
++    public void setEntityTypeId(String entityTypeId) {
++        this.entityTypeId = entityTypeId;
++    }
++
++    public String getOwnerId() {
++        return ownerId;
++    }
++
++    public void setOwnerId(String ownerId) {
++        this.ownerId = ownerId;
++    }
++
++    public String getParentEntityId() {
++        return parentEntityId;
++    }
++
++    public void setParentEntityId(String parentEntityId) {
++        this.parentEntityId = parentEntityId;
++    }
++
++    public String getName() {
++        return name;
++    }
++
++    public void setName(String name) {
++        this.name = name;
++    }
++
++    public String getDescription() {
++        return description;
++    }
++
++    public void setDescription(String description) {
++        this.description = description;
++    }
++
++    public byte[] getBinaryData() {
++        return binaryData;
++    }
++
++    public void setBinaryData(byte[] binaryData) {
++        this.binaryData = binaryData;
++    }
++
++    public String getFullText() {
++        return fullText;
++    }
++
++    public void setFullText(String fullText) {
++        this.fullText = fullText;
++    }
++
++    public double getSharedCount() {
++        return sharedCount;
++    }
++
++    public void setSharedCount(double sharedCount) {
++        this.sharedCount = sharedCount;
++    }
++
++    public double getOriginalEntityCreationTime() {
++        return originalEntityCreationTime;
++    }
++
++    public void setOriginalEntityCreationTime(double originalEntityCreationTime) {
++        this.originalEntityCreationTime = originalEntityCreationTime;
++    }
++
++    public double getCreatedTime() {
++        return createdTime;
++    }
++
++    public void setCreatedTime(double createdTime) {
++        this.createdTime = createdTime;
++    }
++
++    public double getUpdatedTime() {
++        return updatedTime;
++    }
++
++    public void setUpdatedTime(double updatedTime) {
++        this.updatedTime = updatedTime;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/EntitySearchField.java
index 0000000,0000000..7adc461
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/EntitySearchField.java
@@@ -1,0 -1,0 +1,14 @@@
++package org.apache.custos.sharing.service.core.models;
++
++public enum EntitySearchField {
++    NAME,
++    DESCRIPTION,
++    FULL_TEXT,
++    PARRENT_ENTITY_ID,
++    OWNER_ID,
++    PERMISSION_TYPE_ID,
++    CREATED_TIME,
++    UPDATED_TIME,
++    ENTITY_TYPE_ID,
++    SHARED_COUNT
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/EntityType.java
index 0000000,0000000..1df393d
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/EntityType.java
@@@ -1,0 -1,0 +1,58 @@@
++package org.apache.custos.sharing.service.core.models;
++
++public class EntityType {
++    private String entityTypeId;
++    private String domainId;
++    private String name;
++    private String description;
++    private double createdTime;
++    private double updatedTime;
++
++    public String getEntityTypeId() {
++        return entityTypeId;
++    }
++
++    public void setEntityTypeId(String entityTypeId) {
++        this.entityTypeId = entityTypeId;
++    }
++
++    public String getDomainId() {
++        return domainId;
++    }
++
++    public void setDomainId(String domainId) {
++        this.domainId = domainId;
++    }
++
++    public String getName() {
++        return name;
++    }
++
++    public void setName(String name) {
++        this.name = name;
++    }
++
++    public String getDescription() {
++        return description;
++    }
++
++    public void setDescription(String description) {
++        this.description = description;
++    }
++
++    public double getCreatedTime() {
++        return createdTime;
++    }
++
++    public void setCreatedTime(double createdTime) {
++        this.createdTime = createdTime;
++    }
++
++    public double getUpdatedTime() {
++        return updatedTime;
++    }
++
++    public void setUpdatedTime(double updatedTime) {
++        this.updatedTime = updatedTime;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/GroupAdmin.java
index 0000000,0000000..613e806
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/GroupAdmin.java
@@@ -1,0 -1,0 +1,33 @@@
++package org.apache.custos.sharing.service.core.models;
++
++public class GroupAdmin {
++    private String groupId;
++    private String domainId;
++    private String adminId;
++
++    public String getGroupId() {
++        return groupId;
++    }
++
++    public void setGroupId(String groupId) {
++        this.groupId = groupId;
++    }
++
++    public String getDomainId() {
++        return domainId;
++    }
++
++    public void setDomainId(String domainId) {
++        this.domainId = domainId;
++    }
++
++    public String getAdminId() {
++        return adminId;
++    }
++
++    public void setAdminId(String adminId) {
++        this.adminId = adminId;
++    }
++
++
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/GroupCardinality.java
index 0000000,0000000..cf4d1e2
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/GroupCardinality.java
@@@ -1,0 -1,0 +1,6 @@@
++package org.apache.custos.sharing.service.core.models;
++
++public enum GroupCardinality {
++    SINGLE_USER,
++    MULTI_USER
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/GroupChildType.java
index 0000000,0000000..de7a887
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/GroupChildType.java
@@@ -1,0 -1,0 +1,6 @@@
++package org.apache.custos.sharing.service.core.models;
++
++public enum GroupChildType {
++        USER,
++        GROUP
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/GroupMembership.java
index 0000000,0000000..d07a002
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/GroupMembership.java
@@@ -1,0 -1,0 +1,60 @@@
++package org.apache.custos.sharing.service.core.models;
++
++public class GroupMembership {
++
++    private String parentId;
++    private String childId;
++    private String domainId;
++    private GroupChildType childType;
++    private double createdTime;
++    private double updatedTime;
++
++    public String getParentId() {
++        return parentId;
++    }
++
++    public void setParentId(String parentId) {
++        this.parentId = parentId;
++    }
++
++    public String getChildId() {
++        return childId;
++    }
++
++    public void setChildId(String childId) {
++        this.childId = childId;
++    }
++
++    public String getDomainId() {
++        return domainId;
++    }
++
++    public void setDomainId(String domainId) {
++        this.domainId = domainId;
++    }
++
++    public GroupChildType getChildType() {
++        return childType;
++    }
++
++    public void setChildType(GroupChildType childType) {
++        this.childType = childType;
++    }
++
++    public double getCreatedTime() {
++        return createdTime;
++    }
++
++    public void setCreatedTime(double createdTime) {
++        this.createdTime = createdTime;
++    }
++
++    public double getUpdatedTime() {
++        return updatedTime;
++    }
++
++    public void setUpdatedTime(double updatedTime) {
++        this.updatedTime = updatedTime;
++    }
++
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/GroupType.java
index 0000000,0000000..9b00cff
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/GroupType.java
@@@ -1,0 -1,0 +1,6 @@@
++package org.apache.custos.sharing.service.core.models;
++
++public enum GroupType {
++    DOMAIN_LEVEL_GROUP,
++    USER_LEVEL_GROUP
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/PermissionType.java
index 0000000,0000000..1ae87c2
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/PermissionType.java
@@@ -1,0 -1,0 +1,60 @@@
++package org.apache.custos.sharing.service.core.models;
++
++public class PermissionType {
++
++    private String permissionTypeId;
++    private String domainId;
++    private String name;
++    private String description;
++    private double createdTime;
++    private double updatedTime;
++
++    public String getPermissionTypeId() {
++        return permissionTypeId;
++    }
++
++    public void setPermissionTypeId(String permissionTypeId) {
++        this.permissionTypeId = permissionTypeId;
++    }
++
++    public String getDomainId() {
++        return domainId;
++    }
++
++    public void setDomainId(String domainId) {
++        this.domainId = domainId;
++    }
++
++    public String getName() {
++        return name;
++    }
++
++    public void setName(String name) {
++        this.name = name;
++    }
++
++    public String getDescription() {
++        return description;
++    }
++
++    public void setDescription(String description) {
++        this.description = description;
++    }
++
++    public double getCreatedTime() {
++        return createdTime;
++    }
++
++    public void setCreatedTime(double createdTime) {
++        this.createdTime = createdTime;
++    }
++
++    public double getUpdatedTime() {
++        return updatedTime;
++    }
++
++    public void setUpdatedTime(double updatedTime) {
++        this.updatedTime = updatedTime;
++    }
++
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/SearchCondition.java
index 0000000,0000000..3b227a2
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/SearchCondition.java
@@@ -1,0 -1,0 +1,10 @@@
++package org.apache.custos.sharing.service.core.models;
++
++public enum SearchCondition {
++    EQUAL,
++    LIKE,
++    FULL_TEXT,
++    GTE,
++    LTE,
++    NOT
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/SearchCriteria.java
index 0000000,0000000..f053527
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/SearchCriteria.java
@@@ -1,0 -1,0 +1,31 @@@
++package org.apache.custos.sharing.service.core.models;
++
++public class SearchCriteria {
++    private EntitySearchField searchField;
++    private String value;
++    private SearchCondition searchCondition;
++
++    public EntitySearchField getSearchField() {
++        return searchField;
++    }
++
++    public void setSearchField(EntitySearchField searchField) {
++        this.searchField = searchField;
++    }
++
++    public String getValue() {
++        return value;
++    }
++
++    public void setValue(String value) {
++        this.value = value;
++    }
++
++    public SearchCondition getSearchCondition() {
++        return searchCondition;
++    }
++
++    public void setSearchCondition(SearchCondition searchCondition) {
++        this.searchCondition = searchCondition;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/Sharing.java
index 0000000,0000000..83f22ee
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/Sharing.java
@@@ -1,0 -1,0 +1,78 @@@
++package org.apache.custos.sharing.service.core.models;
++
++public class Sharing {
++
++    private String permissionTypeId;
++    private String entityId;
++    private String groupId;
++    private SharingType sharingType;
++    private String domainId;
++    private String inheritedParentId;
++    private double createdTime;
++    private double updatedTime;
++
++    public String getPermissionTypeId() {
++        return permissionTypeId;
++    }
++
++    public void setPermissionTypeId(String permissionTypeId) {
++        this.permissionTypeId = permissionTypeId;
++    }
++
++    public String getEntityId() {
++        return entityId;
++    }
++
++    public void setEntityId(String entityId) {
++        this.entityId = entityId;
++    }
++
++    public String getGroupId() {
++        return groupId;
++    }
++
++    public void setGroupId(String groupId) {
++        this.groupId = groupId;
++    }
++
++    public SharingType getSharingType() {
++        return sharingType;
++    }
++
++    public void setSharingType(SharingType sharingType) {
++        this.sharingType = sharingType;
++    }
++
++    public String getDomainId() {
++        return domainId;
++    }
++
++    public void setDomainId(String domainId) {
++        this.domainId = domainId;
++    }
++
++    public String getInheritedParentId() {
++        return inheritedParentId;
++    }
++
++    public void setInheritedParentId(String inheritedParentId) {
++        this.inheritedParentId = inheritedParentId;
++    }
++
++    public double getCreatedTime() {
++        return createdTime;
++    }
++
++    public void setCreatedTime(double createdTime) {
++        this.createdTime = createdTime;
++    }
++
++    public double getUpdatedTime() {
++        return updatedTime;
++    }
++
++    public void setUpdatedTime(double updatedTime) {
++        this.updatedTime = updatedTime;
++    }
++
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/SharingType.java
index 0000000,0000000..ccc9a59
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/SharingType.java
@@@ -1,0 -1,0 +1,7 @@@
++package org.apache.custos.sharing.service.core.models;
++
++public enum SharingType {
++    DIRECT_NON_CASCADING,
++    DIRECT_CASCADING,
++    INDIRECT_CASCADING
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/User.java
index 0000000,0000000..f4f2174
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/User.java
@@@ -1,0 -1,0 +1,85 @@@
++package org.apache.custos.sharing.service.core.models;
++
++public class User {
++    private String userId;
++    private String domainId;
++    private String userName;
++    private String firstName;
++    private String lastName;
++    private String email;
++    private byte icon;
++    private double createdTime;
++    private double updatedTime;
++
++    public String getUserId() {
++        return userId;
++    }
++
++    public void setUserId(String userId) {
++        this.userId = userId;
++    }
++
++    public String getDomainId() {
++        return domainId;
++    }
++
++    public void setDomainId(String domainId) {
++        this.domainId = domainId;
++    }
++
++    public String getUserName() {
++        return userName;
++    }
++
++    public void setUserName(String userName) {
++        this.userName = userName;
++    }
++
++    public String getFirstName() {
++        return firstName;
++    }
++
++    public void setFirstName(String firstName) {
++        this.firstName = firstName;
++    }
++
++    public String getLastName() {
++        return lastName;
++    }
++
++    public void setLastName(String lastName) {
++        this.lastName = lastName;
++    }
++
++    public String getEmail() {
++        return email;
++    }
++
++    public void setEmail(String email) {
++        this.email = email;
++    }
++
++    public byte getIcon() {
++        return icon;
++    }
++
++    public void setIcon(byte icon) {
++        this.icon = icon;
++    }
++
++    public double getCreatedTime() {
++        return createdTime;
++    }
++
++    public void setCreatedTime(double createdTime) {
++        this.createdTime = createdTime;
++    }
++
++    public double getUpdatedTime() {
++        return updatedTime;
++    }
++
++    public void setUpdatedTime(double updatedTime) {
++        this.updatedTime = updatedTime;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/UserGroup.java
index 0000000,0000000..16457f0
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/models/UserGroup.java
@@@ -1,0 -1,0 +1,97 @@@
++package org.apache.custos.sharing.service.core.models;
++
++import java.util.List;
++
++public class UserGroup {
++
++    private String groupId;
++    private String domainId;
++    private String name;
++    private String description;
++    private String ownerId;
++    private GroupType groupType;
++    private GroupCardinality groupCardinality;
++    private double createdTime;
++    private double updatedTime;
++    private List<GroupAdmin> groupAdmins;
++
++    public String getGroupId() {
++        return groupId;
++    }
++
++    public void setGroupId(String groupId) {
++        this.groupId = groupId;
++    }
++
++    public String getDomainId() {
++        return domainId;
++    }
++
++    public void setDomainId(String domainId) {
++        this.domainId = domainId;
++    }
++
++    public String getName() {
++        return name;
++    }
++
++    public void setName(String name) {
++        this.name = name;
++    }
++
++    public String getDescription() {
++        return description;
++    }
++
++    public void setDescription(String description) {
++        this.description = description;
++    }
++
++    public String getOwnerId() {
++        return ownerId;
++    }
++
++    public void setOwnerId(String ownerId) {
++        this.ownerId = ownerId;
++    }
++
++    public GroupType getGroupType() {
++        return groupType;
++    }
++
++    public void setGroupType(GroupType groupType) {
++        this.groupType = groupType;
++    }
++
++    public GroupCardinality getGroupCardinality() {
++        return groupCardinality;
++    }
++
++    public void setGroupCardinality(GroupCardinality groupCardinality) {
++        this.groupCardinality = groupCardinality;
++    }
++
++    public double getCreatedTime() {
++        return createdTime;
++    }
++
++    public void setCreatedTime(double createdTime) {
++        this.createdTime = createdTime;
++    }
++
++    public double getUpdatedTime() {
++        return updatedTime;
++    }
++
++    public void setUpdatedTime(double updatedTime) {
++        this.updatedTime = updatedTime;
++    }
++
++    public List<GroupAdmin> getGroupAdmins() {
++        return groupAdmins;
++    }
++
++    public void setGroupAdmins(List<GroupAdmin> groupAdmins) {
++        this.groupAdmins = groupAdmins;
++    }
++}
diff --cc custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/service/SharingRegistryService.java
index 0000000,0000000..fef39c9
new file mode 100644
--- /dev/null
+++ b/custos-sharing-registry-service/sharing-service-core/src/main/java/org/apache/custos/sharing/service/core/service/SharingRegistryService.java
@@@ -1,0 -1,0 +1,1216 @@@
++/**
++ *
++ * 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.service.core.service;
++
++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.service.core.models.*;
++import org.apache.custos.sharing.service.core.db.entities.*;
++import org.apache.custos.sharing.service.core.db.repositories.*;
++import org.apache.custos.sharing.service.core.db.utils.DBConstants;
++import org.apache.custos.sharing.service.core.db.utils.SharingRegistryDBInitConfig;
++import org.apache.custos.sharing.service.core.exceptions.DuplicateEntryException;
++import org.apache.custos.sharing.service.core.exceptions.SharingRegistryException;
++import org.apache.thrift.TException;
++import org.slf4j.Logger;
++import org.slf4j.LoggerFactory;
++import org.springframework.beans.factory.annotation.Autowired;
++import org.springframework.stereotype.Service;
++
++import java.lang.reflect.Field;
++import java.lang.reflect.Modifier;
++import java.util.*;
++
++@Service
++public class SharingRegistryService {
++    private final static Logger logger = LoggerFactory.getLogger(SharingRegistryService.class);
++
++    public static String OWNER_PERMISSION_NAME = "OWNER";
++    public static String SHARING_CPI_VERSION = "1.0";
++
++    public SharingRegistryService(SharingRegistryDBInitConfig sharingRegistryDBInitConfig)  throws ApplicationSettingsException {
++        DBInitializer.initializeDB(sharingRegistryDBInitConfig);
++    }
++
++    public String getAPIVersion() {
++        return SHARING_CPI_VERSION;
++    }
++
++    /**
++     * * Domain Operations
++     * *
++     */
++
++    public String createDomain(Domain domain) throws SharingRegistryException, DuplicateEntryException {
++        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));
++        }
++    }
++
++    public boolean updateDomain(Domain domain) throws SharingRegistryException {
++        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
++     */
++    public boolean isDomainExists(String domainId) throws SharingRegistryException {
++        try{
++            return (new DomainRepository()).isExists(domainId);
++        }catch (Throwable ex) {
++            logger.error(ex.getMessage(), ex);
++            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
++        }
++    }
++
++    public boolean deleteDomain(String domainId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public Domain getDomain(String domainId) throws SharingRegistryException {
++        try{
++            return (new DomainRepository()).get(domainId);
++        }catch (Throwable ex) {
++            logger.error(ex.getMessage(), ex);
++            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
++        }
++    }
++
++    public List<Domain> getDomains(int offset, int limit) throws SharingRegistryException {
++        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
++     * *
++     */
++    public String createUser(User user) throws SharingRegistryException, DuplicateEntryException {
++        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));
++        }
++    }
++
++    public boolean updatedUser(User user) throws SharingRegistryException {
++        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
++     */
++    public boolean isUserExists(String domainId, String userId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public boolean deleteUser(String domainId, String userId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public User getUser(String domainId, String userId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public List<User> getUsers(String domain, int offset, int limit) throws SharingRegistryException {
++        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
++     * *
++     */
++    public String createGroup(UserGroup group) throws DuplicateEntryException, SharingRegistryException{
++        try {
++            UserGroupPK userGroupPK = new UserGroupPK();
++            userGroupPK.setGroupId(group.getGroupId());
++            userGroupPK.setDomainId(group.getDomainId());
++            if ((new UserGroupRepository()).get(userGroupPK) != null)
++                throw new DuplicateEntryException("There exists 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());
++            addGroupAdmins(group.getDomainId(), group.getGroupId(), group.getGroupAdmins());
++            return group.getGroupId();
++        } catch (DuplicateEntryException ex) {
++            logger.error(ex.getMessage(), ex);
++            throw ex;
++        } catch (Throwable ex) {
++            logger.error(ex.getMessage(), ex);
++            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
++        }
++    }
++
++    public boolean updateGroup(UserGroup group) throws SharingRegistryException {
++        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
++     */
++
++    public boolean isGroupExists(String domainId, String groupId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public boolean deleteGroup(String domainId, String groupId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public UserGroup getGroup(String domainId, String groupId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public List<UserGroup> getGroups(String domain, int offset, int limit) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public boolean addUsersToGroup(String domainId, List<String> userIds, String groupId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public boolean removeUsersFromGroup(String domainId, List<String> userIds, String groupId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public boolean transferGroupOwnership(String domainId, String groupId, String newOwnerId) throws SharingRegistryException {
++        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;
++    }
++
++    public boolean addGroupAdmins(String domainId, String groupId, List<GroupAdmin> admins) throws SharingRegistryException {
++        try{
++            List<User> groupUser = getGroupMembersOfTypeUser(domainId, groupId, 0, -1);
++
++            for (GroupAdmin admin: admins) {
++                String adminId = admin.getAdminId();
++                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");
++
++                (new GroupAdminRepository()).create(admin);
++            }
++            return true;
++        }
++        catch (Throwable ex) {
++            logger.error(ex.getMessage(), ex);
++            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
++        }
++    }
++
++    public boolean removeGroupAdmins(String domainId, String groupId, List<String> adminIds) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public boolean hasAdminAccess(String domainId, String groupId, String adminId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public boolean hasOwnerAccess(String domainId, String groupId, String ownerId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public List<User> getGroupMembersOfTypeUser(String domainId, String groupId, int offset, int limit) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public List<UserGroup> getGroupMembersOfTypeGroup(String domainId, String groupId, int offset, int limit) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public boolean addChildGroupsToParentGroup(String domainId, List<String> childIds, String groupId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public boolean removeChildGroupFromParentGroup(String domainId, String childId, String groupId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public List<UserGroup> getAllMemberGroupsForUser(String domainId, String userId) throws SharingRegistryException {
++        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
++     * *
++     */
++    public String createEntityType(EntityType entityType) throws SharingRegistryException, DuplicateEntryException {
++        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));
++        }
++    }
++
++    public boolean updateEntityType(EntityType entityType) throws SharingRegistryException {
++        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
++     */
++    public boolean isEntityTypeExists(String domainId, String entityTypeId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public boolean deleteEntityType(String domainId, String entityTypeId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public EntityType getEntityType(String domainId, String entityTypeId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public List<EntityType> getEntityTypes(String domain, int offset, int limit) throws SharingRegistryException {
++        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
++     * *
++     */
++    public String createPermissionType(PermissionType permissionType) throws SharingRegistryException, DuplicateEntryException {
++        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));
++        }
++    }
++
++    public boolean updatePermissionType(PermissionType permissionType) throws SharingRegistryException {
++        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
++     */
++    public boolean isPermissionExists(String domainId, String permissionId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public boolean deletePermissionType(String domainId, String permissionTypeId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public PermissionType getPermissionType(String domainId, String permissionTypeId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public List<PermissionType> getPermissionTypes(String domain, int offset, int limit) throws SharingRegistryException {
++        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
++     * *
++     */
++    public String createEntity(Entity entity) throws SharingRegistryException, DuplicateEntryException {
++        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);
++            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
++        }
++    }
++
++    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);
++                }
++            }
++
++    public boolean updateEntity(Entity entity) throws SharingRegistryException {
++        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
++     */
++    public boolean isEntityExists(String domainId, String entityId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public boolean deleteEntity(String domainId, String entityId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public Entity getEntity(String domainId, String entityId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public List<Entity> searchEntities(String domainId, String userId, List<SearchCriteria> filters,
++                                       int offset, int limit) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public List<User> getListOfSharedUsers(String domainId, String entityId, String permissionTypeId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public List<User> getListOfDirectlySharedUsers(String domainId, String entityId, String permissionTypeId)
++            throws SharingRegistryException {
++        try{
++            return (new UserRepository()).getDirectlyAccessibleUsers(domainId, entityId, permissionTypeId);
++        }catch (Throwable ex) {
++            logger.error(ex.getMessage(), ex);
++            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
++        }
++    }
++
++    public List<UserGroup> getListOfSharedGroups(String domainId, String entityId, String permissionTypeId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public List<UserGroup> getListOfDirectlySharedGroups(String domainId, String entityId, String permissionTypeId)
++            throws SharingRegistryException {
++        try{
++            return (new UserGroupRepository()).getDirectlyAccessibleGroups(domainId, entityId, permissionTypeId);
++        }catch (Throwable ex) {
++            logger.error(ex.getMessage(), ex);
++            throw new SharingRegistryException(ex.getMessage() + " Stack trace:" + ExceptionUtils.getStackTrace(ex));
++        }
++    }
++
++    /**
++     * Sharing Entity with Users and Groups
++     * @param domainId
++     * @param entityId
++     * @param userList
++     * @param permissionTypeId
++     * @param cascadePermission
++     * @return
++     * @throws SharingRegistryException
++     * @throws TException
++     */
++    public boolean shareEntityWithUsers(String domainId, String entityId, List<String> userList, String permissionTypeId, boolean cascadePermission) throws SharingRegistryException {
++        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));
++        }
++    }
++
++    public boolean shareEntityWithGroups(String domainId, String entityId, List<String> groupList, String permissionTypeId, boolean cascadePermission) throws SharingRegistryException {
++        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 {
++        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));
++        }
++    }
++
++    public boolean revokeEntitySharingFromUsers(String domainId, String entityId, List<String> userList, String permissionTypeId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++
++    public boolean revokeEntitySharingFromGroups(String domainId, String entityId, List<String> groupList, String permissionTypeId) throws SharingRegistryException {
++        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));
++        }
++    }
++
++
++    public boolean userHasAccess(String domainId, String userId, String entityId, String permissionTypeId) throws SharingRegistryException {
++        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 --cc pom.xml
index 2a1519b,e0524c7..5168d60
--- a/pom.xml
+++ b/pom.xml
@@@ -31,9 -30,8 +31,10 @@@
          <log4j.version>1.2.17</log4j.version>
          <thrift.version>0.12.0</thrift.version>
          <openjpa.version>2.4.3</openjpa.version>
-         <junit.version>4.12</junit.version>
 +        <mysql.connector.version>5.1.34</mysql.connector.version>
 +        <maven.assembly.plugin>3.1.1</maven.assembly.plugin>
+         <junit.version>4.8.1</junit.version>
+         <jmockit.version>1.8</jmockit.version>
      </properties>
      <dependencies>
          <dependency>