You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by is...@apache.org on 2021/06/01 17:59:01 UTC

[airavata-data-lake] 18/46: Add merger for updates

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

isjarana pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata-data-lake.git

commit dc26af311ae5e406a4e8f18afaf48db91d5777a2
Author: Isuru Ranawaka <ir...@gmail.com>
AuthorDate: Wed Mar 24 14:46:37 2021 -0400

    Add merger for updates
---
 .../airavata/datalake/metadata/clients/Test.java   |  31 +++++-
 .../airavata/datalake/metadata/AppConfig.java      |  47 +++++----
 .../datalake/metadata/Neo4JServiceInitializer.java |   2 +
 .../neo4j/curd/operators/GenericService.java       |  14 ++-
 .../backend/neo4j/curd/operators/GroupService.java |   1 +
 .../neo4j/curd/operators/GroupServiceImpl.java     |  28 ++++++
 .../neo4j/curd/operators/ResourceService.java      |   4 +
 .../neo4j/curd/operators/ResourceServiceImpl.java  |  52 +++++++++-
 .../backend/neo4j/curd/operators/Service.java      |   6 +-
 .../neo4j/curd/operators/TenantService.java        |   2 +
 .../neo4j/curd/operators/TenantServiceImpl.java    |  34 +++++++
 .../backend/neo4j/curd/operators/UserService.java  |   1 +
 .../neo4j/curd/operators/UserServiceImpl.java      |  28 ++++++
 .../metadata/backend/neo4j/model/nodes/Entity.java |  12 +++
 .../metadata/handlers/GroupServiceHandler.java     |  79 ++++++++++++---
 .../metadata/handlers/ResourceServiceHandler.java  | 111 ++++++++++++++++++---
 .../metadata/handlers/TenantServiceHandler.java    |  78 +++++++++++++--
 .../metadata/handlers/UserServiceHandler.java      |  48 ++++++++-
 .../metadata/interceptors/Authenticator.java       |  19 ++++
 .../interceptors/InterceptorPipelineExecutor.java  |  69 +++++++++++++
 .../metadata/interceptors/ServiceInterceptor.java  |   7 ++
 .../datalake/metadata/mergers/GenericMerger.java   |  46 +++++++++
 .../airavata/datalake/metadata/mergers/Merger.java |   9 ++
 .../metadata/parsers/ExecutionContext.java         |   4 +
 .../datalake/metadata/parsers/GroupParser.java     |  17 +++-
 .../airavata/datalake/metadata/parsers/Parser.java |   5 +-
 .../datalake/metadata/parsers/ResourceParser.java  |  20 +++-
 .../datalake/metadata/parsers/TenantParser.java    |  52 +++++++---
 .../datalake/metadata/parsers/UserParser.java      |  18 +++-
 .../stub/src/main/proto/resource/Resource.proto    |  20 ++++
 .../stub/src/main/proto/tenant/Tenant.proto        |   6 +-
 31 files changed, 776 insertions(+), 94 deletions(-)

diff --git a/metadata-service/db-service/client/src/main/java/org/apache/airavata/datalake/metadata/clients/Test.java b/metadata-service/db-service/client/src/main/java/org/apache/airavata/datalake/metadata/clients/Test.java
index a506d75..b70c246 100644
--- a/metadata-service/db-service/client/src/main/java/org/apache/airavata/datalake/metadata/clients/Test.java
+++ b/metadata-service/db-service/client/src/main/java/org/apache/airavata/datalake/metadata/clients/Test.java
@@ -101,7 +101,36 @@ public class Test {
                 .setTenant(tenant)
                 .build();
 
-        stub.createTenant(request);
+//        stub.createTenant(request);
+//
+
+//        ResourceMetadataServiceGrpc.ResourceMetadataServiceBlockingStub resourceMetadataServiceBlockingStub = serviceClient.resource();
+//
+//        ResourcePermissionRequest permissionRequest = ResourcePermissionRequest
+//                .newBuilder()
+//                .setPermissionType("READ")
+//                .setUsername("TestingUserA")
+//                .setResourceName("R5")
+//                .setTenantId("100010402")
+//                .build();
+//      ResourcePermissionResponse response =   resourceMetadataServiceBlockingStub.hasAccess(permissionRequest);
+
+
+//        TenantMetadataAPIRequest tenantMetadataAPIRequest = TenantMetadataAPIRequest
+//                .newBuilder()
+//                .setTenant(tenant)
+//                .build();
+//
+//        stub.deleteTenant(tenantMetadataAPIRequest);
+
+        tenant = tenant.toBuilder().setDomain("testing.com").build();
+
+
+        TenantMetadataAPIRequest tenantMetadataAPIRequest = TenantMetadataAPIRequest
+                .newBuilder()
+                .setTenant(tenant)
+                .build();
+        stub.updateTenant(tenantMetadataAPIRequest);
 
     }
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/AppConfig.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/AppConfig.java
index 0e03c32..05ee7a4 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/AppConfig.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/AppConfig.java
@@ -1,15 +1,18 @@
 package org.apache.airavata.datalake.metadata;
 
+import io.grpc.ServerInterceptor;
 import org.apache.airavata.datalake.metadata.backend.Connector;
-import org.apache.airavata.datalake.metadata.backend.neo4j.curd.operators.ResourceServiceImpl;
-import org.apache.airavata.datalake.metadata.backend.neo4j.curd.operators.SearchOperator;
 import org.apache.airavata.datalake.metadata.backend.neo4j.curd.operators.TenantServiceImpl;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Group;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Resource;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Tenant;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.User;
+import org.apache.airavata.datalake.metadata.interceptors.Authenticator;
+import org.apache.airavata.datalake.metadata.interceptors.InterceptorPipelineExecutor;
+import org.apache.airavata.datalake.metadata.interceptors.ServiceInterceptor;
 import org.dozer.DozerBeanMapper;
 import org.dozer.loader.api.BeanMappingBuilder;
+import org.lognet.springboot.grpc.GRpcGlobalInterceptor;
 import org.neo4j.ogm.cypher.ComparisonOperator;
 import org.neo4j.ogm.cypher.Filter;
 import org.slf4j.Logger;
@@ -18,8 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Stack;
 
 
 @Configuration
@@ -132,26 +134,37 @@ public class AppConfig {
         tenant.add(resource, 0, 0, null);
 
         TenantServiceImpl tenantService = new TenantServiceImpl(connector);
-        tenantService.createOrUpdate(tenant);
+//        tenantService.createOrUpdate(tenant);
 
         Filter filter = new Filter("name", ComparisonOperator.EQUALS, "R3");
 
-        ResourceServiceImpl resourceService = new ResourceServiceImpl(connector);
-        SearchOperator searchOperator = new SearchOperator();
-        searchOperator.setKey("name");
-        searchOperator.setValue("R2");
-        searchOperator.setComparisonOperator(ComparisonOperator.EQUALS);
-        List searchList = new ArrayList<>();
-        searchList.add(searchOperator);
-        List<Resource> collections = (List<Resource>) resourceService.search(searchList);
-        LOGGER.info("Size", collections.size());
-        for (Resource collection : collections) {
-            LOGGER.info("#############" + collection.getName() + "Created At" + collection.getCreatedAt());
-        }
+//        ResourceServiceImpl resourceService = new ResourceServiceImpl(connector);
+//        SearchOperator searchOperator = new SearchOperator();
+//        searchOperator.setKey("name");
+//        searchOperator.setValue("R2");
+//        searchOperator.setComparisonOperator(ComparisonOperator.EQUALS);
+//        List searchList = new ArrayList<>();
+//        searchList.add(searchOperator);
+//        List<Resource> collections = (List<Resource>) resourceService.search(searchList);
+//        LOGGER.info("Size", collections.size());
+//        for (Resource collection : collections) {
+//            LOGGER.info("#############" + collection.getName() + "Created At" + collection.getCreatedAt());
+//        }
 
 
         return tenant;
     }
 
+    @Bean
+    public Stack<ServiceInterceptor> getInterceptorSet(Authenticator authInterceptor) {
+        Stack<ServiceInterceptor> interceptors = new Stack<>();
+        interceptors.add(authInterceptor);
+        return interceptors;
+    }
 
+    @Bean
+    @GRpcGlobalInterceptor
+    ServerInterceptor validationInterceptor(Stack<ServiceInterceptor> integrationServiceInterceptors) {
+        return new InterceptorPipelineExecutor(integrationServiceInterceptors);
+    }
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/Neo4JServiceInitializer.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/Neo4JServiceInitializer.java
index 0850cc7..1e414b7 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/Neo4JServiceInitializer.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/Neo4JServiceInitializer.java
@@ -11,4 +11,6 @@ public class Neo4JServiceInitializer {
     public static void main(String[] args) {
         SpringApplication.run(Neo4JServiceInitializer.class, args);
     }
+
+
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/GenericService.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/GenericService.java
index a199dfe..3d44dbd 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/GenericService.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/GenericService.java
@@ -9,14 +9,15 @@ import org.neo4j.ogm.session.Session;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.Closeable;
+import java.io.IOException;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
 
 
-public abstract class GenericService<T> implements Service<T> {
+public abstract class GenericService<T> implements Service<T>, Closeable {
 
     private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
 
@@ -77,8 +78,8 @@ public abstract class GenericService<T> implements Service<T> {
     }
 
     @Override
-    public Iterable<Map<String, Object>> execute(String query) {
-        return session.query(query, Collections.EMPTY_MAP);
+    public Iterable<Map<String, Object>> execute(String query, Map<String, ?> parameterMap) {
+        return session.query(query, parameterMap);
     }
 
     @Override
@@ -87,4 +88,9 @@ public abstract class GenericService<T> implements Service<T> {
     }
 
     abstract Class<T> getEntityType();
+
+    @Override
+    public void close() throws IOException {
+        this.session.clear();
+    }
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/GroupService.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/GroupService.java
index 8e870fa..6e34f19 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/GroupService.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/GroupService.java
@@ -1,4 +1,5 @@
 package org.apache.airavata.datalake.metadata.backend.neo4j.curd.operators;
 
 public interface GroupService {
+
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/GroupServiceImpl.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/GroupServiceImpl.java
index 1b7c9ad..fcdaf9e 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/GroupServiceImpl.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/GroupServiceImpl.java
@@ -1,7 +1,13 @@
 package org.apache.airavata.datalake.metadata.backend.neo4j.curd.operators;
 
 import org.apache.airavata.datalake.metadata.backend.Connector;
+import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Entity;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Group;
+import org.neo4j.ogm.cypher.ComparisonOperator;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
 
 public class GroupServiceImpl extends GenericService<Group> implements GroupService {
 
@@ -13,4 +19,26 @@ public class GroupServiceImpl extends GenericService<Group> implements GroupServ
     Class<Group> getEntityType() {
         return Group.class;
     }
+
+    @Override
+    public List<Group> find( Group group) {
+        List<SearchOperator> searchOperatorList = new ArrayList<>();
+        if (group.getTenantId() != null) {
+            SearchOperator searchOperator = new SearchOperator();
+            searchOperator.setKey("tenant_id");
+            searchOperator.setValue(group.getTenantId());
+            searchOperator.setComparisonOperator(ComparisonOperator.EQUALS);
+            searchOperatorList.add(searchOperator);
+        }
+
+        if (group.getName() != null) {
+            SearchOperator searchOperator = new SearchOperator();
+            searchOperator.setKey("name");
+            searchOperator.setValue(group.getName());
+            searchOperator.setComparisonOperator(ComparisonOperator.EQUALS);
+            searchOperatorList.add(searchOperator);
+        }
+        Collection<Group> groups = super.search(searchOperatorList);
+        return new ArrayList<>(groups);
+    }
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/ResourceService.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/ResourceService.java
index be6d06c..36b57eb 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/ResourceService.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/ResourceService.java
@@ -1,4 +1,8 @@
 package org.apache.airavata.datalake.metadata.backend.neo4j.curd.operators;
 
 public interface ResourceService {
+
+    public boolean hasAccess(String username, String resourceName, String permissionType, String tenantId);
+
+
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/ResourceServiceImpl.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/ResourceServiceImpl.java
index e1b8a35..fe7e2d9 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/ResourceServiceImpl.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/ResourceServiceImpl.java
@@ -1,9 +1,14 @@
 package org.apache.airavata.datalake.metadata.backend.neo4j.curd.operators;
 
 import org.apache.airavata.datalake.metadata.backend.Connector;
+import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Entity;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Resource;
+import org.neo4j.ogm.cypher.ComparisonOperator;
 
-public class ResourceServiceImpl extends GenericService<Resource> implements UserService {
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class ResourceServiceImpl extends GenericService<Resource> implements ResourceService {
 
     public ResourceServiceImpl(Connector connector) {
         super(connector);
@@ -13,4 +18,49 @@ public class ResourceServiceImpl extends GenericService<Resource> implements Use
     Class<Resource> getEntityType() {
         return Resource.class;
     }
+
+
+    @Override
+    public boolean hasAccess(String username, String resourceName, String permissionType, String tenantId) {
+        String query =
+                "match (u:User{name:$username})-[:MEMBER_OF|HAS_CHILD_GROUP*]->(g:Group{tenant_id:$tenantId})" +
+                        "-[r:HAS_ACCESS]->(m:Resource{tenant_id:$tenantId})-[l:HAS_CHILD_RESOURCE*]->  " +
+                        "(p:Resource{tenant_id:$tenantId}) " +
+                        "where r.permission_type=$permissionType   and m.name=$resourceName or  p.name=$resourceName return m,p";
+        Map<String, String> parameterMap = new HashMap<>();
+        parameterMap.put("username", username);
+        parameterMap.put("permissionType", permissionType);
+        parameterMap.put("resourceName", resourceName);
+        parameterMap.put("tenantId", tenantId);
+        Iterable<Map<String, Object>> mapIterable = super.execute(query, parameterMap);
+        AtomicBoolean accessible = new AtomicBoolean(false);
+        mapIterable.forEach(map -> {
+            if (!map.isEmpty()) {
+                accessible.set(true);
+            }
+        });
+        return accessible.get();
+    }
+
+    @Override
+    public List<Resource> find( Resource resource) {
+        List<SearchOperator> searchOperatorList = new ArrayList<>();
+        if (resource.getTenantId() != null) {
+            SearchOperator searchOperator = new SearchOperator();
+            searchOperator.setKey("tenant_id");
+            searchOperator.setValue(resource.getTenantId());
+            searchOperator.setComparisonOperator(ComparisonOperator.EQUALS);
+            searchOperatorList.add(searchOperator);
+        }
+
+        if (resource.getName() != null) {
+            SearchOperator searchOperator = new SearchOperator();
+            searchOperator.setKey("name");
+            searchOperator.setValue(resource.getName());
+            searchOperator.setComparisonOperator(ComparisonOperator.EQUALS);
+            searchOperatorList.add(searchOperator);
+        }
+        Collection<Resource> resources = super.search(searchOperatorList);
+        return new ArrayList<>(resources);
+    }
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/Service.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/Service.java
index 1694973..e1fecb7 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/Service.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/Service.java
@@ -1,5 +1,7 @@
 package org.apache.airavata.datalake.metadata.backend.neo4j.curd.operators;
 
+import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Entity;
+import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Tenant;
 import org.neo4j.ogm.cypher.query.SortOrder;
 
 import java.util.Collection;
@@ -20,8 +22,10 @@ public interface Service<T> {
 
     Iterable<T> sortAndPaging(SortOrder.Direction direction, int pageNumber, int itemsPerPage, String property);
 
-    Iterable<Map<String,Object>> execute(String query);
+    Iterable<Map<String,Object>> execute(String query, Map<String, ?> parameterMap);
 
     void createOrUpdate(T Object);
 
+    public List<T> find(T entity);
+
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/TenantService.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/TenantService.java
index 1034d1a..87c5583 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/TenantService.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/TenantService.java
@@ -1,4 +1,6 @@
 package org.apache.airavata.datalake.metadata.backend.neo4j.curd.operators;
 
 public interface TenantService {
+
+
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/TenantServiceImpl.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/TenantServiceImpl.java
index fb6c776..f727997 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/TenantServiceImpl.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/TenantServiceImpl.java
@@ -1,7 +1,13 @@
 package org.apache.airavata.datalake.metadata.backend.neo4j.curd.operators;
 
 import org.apache.airavata.datalake.metadata.backend.Connector;
+import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Entity;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Tenant;
+import org.neo4j.ogm.cypher.ComparisonOperator;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
 
 public class TenantServiceImpl extends GenericService<Tenant> implements TenantService {
     public TenantServiceImpl(Connector connector) {
@@ -12,4 +18,32 @@ public class TenantServiceImpl extends GenericService<Tenant> implements TenantS
     Class<Tenant> getEntityType() {
         return Tenant.class;
     }
+
+    @Override
+    public List<Tenant> find(Tenant tenant) {
+        List<SearchOperator> searchOperatorList = new ArrayList<>();
+        if (tenant.getTenantId() != null) {
+            SearchOperator searchOperator = new SearchOperator();
+            searchOperator.setKey("tenant_id");
+            searchOperator.setValue(tenant.getTenantId());
+            searchOperator.setComparisonOperator(ComparisonOperator.EQUALS);
+            searchOperatorList.add(searchOperator);
+        }
+
+        if (tenant.getName() != null) {
+            SearchOperator searchOperator = new SearchOperator();
+            searchOperator.setKey("name");
+            searchOperator.setValue(tenant.getName());
+            searchOperator.setComparisonOperator(ComparisonOperator.EQUALS);
+            searchOperatorList.add(searchOperator);
+        }
+        Collection<Tenant> tenants = super.search(searchOperatorList);
+        return new ArrayList<>(tenants);
+    }
+
+
+    @Override
+    public void createOrUpdate(Tenant tenant) {
+        super.createOrUpdate(tenant);
+    }
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/UserService.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/UserService.java
index 737b93a..6efded7 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/UserService.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/UserService.java
@@ -1,4 +1,5 @@
 package org.apache.airavata.datalake.metadata.backend.neo4j.curd.operators;
 
 public interface UserService {
+
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/UserServiceImpl.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/UserServiceImpl.java
index 542cce3..7d24263 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/UserServiceImpl.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/curd/operators/UserServiceImpl.java
@@ -2,6 +2,11 @@ package org.apache.airavata.datalake.metadata.backend.neo4j.curd.operators;
 
 import org.apache.airavata.datalake.metadata.backend.Connector;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.User;
+import org.neo4j.ogm.cypher.ComparisonOperator;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
 
 public class UserServiceImpl extends GenericService<User> implements UserService {
 
@@ -13,4 +18,27 @@ public class UserServiceImpl extends GenericService<User> implements UserService
     Class<User> getEntityType() {
         return User.class;
     }
+
+
+    @Override
+    public List<User> find(User user) {
+        List<SearchOperator> searchOperatorList = new ArrayList<>();
+        if (user.getTenantId() != null) {
+            SearchOperator searchOperator = new SearchOperator();
+            searchOperator.setKey("tenant_id");
+            searchOperator.setValue(user.getTenantId());
+            searchOperator.setComparisonOperator(ComparisonOperator.EQUALS);
+            searchOperatorList.add(searchOperator);
+        }
+
+        if (user.getUsername() != null) {
+            SearchOperator searchOperator = new SearchOperator();
+            searchOperator.setKey("username");
+            searchOperator.setValue(user.getUsername());
+            searchOperator.setComparisonOperator(ComparisonOperator.EQUALS);
+            searchOperatorList.add(searchOperator);
+        }
+        Collection<User> users = super.search(searchOperatorList);
+        return new ArrayList<>(users);
+    }
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/model/nodes/Entity.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/model/nodes/Entity.java
index aba5035..c1a2bcc 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/model/nodes/Entity.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/backend/neo4j/model/nodes/Entity.java
@@ -1,6 +1,7 @@
 package org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes;
 
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.relationships.Has;
+import org.apache.airavata.datalake.metadata.parsers.ExecutionContext;
 import org.neo4j.ogm.annotation.*;
 
 import java.util.HashMap;
@@ -35,6 +36,9 @@ public abstract class Entity {
     @Property(name = "tenant_id")
     private String tenantId;
 
+    @Transient
+    private ExecutionContext executionContext;
+
 
 
     public Long getId() {
@@ -113,4 +117,12 @@ public abstract class Entity {
     public String getSearchableId() {
         return primaryExternalKey+"@"+tenantId;
     }
+
+    public ExecutionContext getExecutionContext() {
+        return executionContext;
+    }
+
+    public void setExecutionContext(ExecutionContext executionContext) {
+        this.executionContext = executionContext;
+    }
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/GroupServiceHandler.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/GroupServiceHandler.java
index fb46b49..e6efab6 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/GroupServiceHandler.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/GroupServiceHandler.java
@@ -3,36 +3,91 @@ package org.apache.airavata.datalake.metadata.handlers;
 import io.grpc.stub.StreamObserver;
 import org.apache.airavata.datalake.metadata.service.*;
 import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 @GRpcService
 public class GroupServiceHandler extends GroupMetadataServiceGrpc.GroupMetadataServiceImplBase {
+    private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceHandler.class);
+
     @Override
-    public void createGroup(GroupMetadataAPIRequest request, StreamObserver<GroupMetadataAPIResponse> responseObserver) {
-        super.createGroup(request, responseObserver);
+    public void createGroup(GroupMetadataAPIRequest request,
+                            StreamObserver<GroupMetadataAPIResponse> responseObserver) {
+        try {
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while creating group " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(new Exception(msg));
+        }
     }
 
     @Override
-    public void getGroup(GroupMetadataAPIRequest request, StreamObserver<Group> responseObserver) {
-        super.getGroup(request, responseObserver);
+    public void getGroup(GroupMetadataAPIRequest request,
+                         StreamObserver<Group> responseObserver) {
+        try {
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while fetching group " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(new Exception(msg));
+        }
     }
 
     @Override
-    public void updateGroup(GroupMetadataAPIRequest request, StreamObserver<GroupMetadataAPIResponse> responseObserver) {
-        super.updateGroup(request, responseObserver);
+    public void updateGroup(GroupMetadataAPIRequest request,
+                            StreamObserver<GroupMetadataAPIResponse> responseObserver) {
+        try {
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while updating group " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(new Exception(msg));
+        }
     }
 
     @Override
-    public void deleteGroup(GroupMetadataAPIRequest request, StreamObserver<GroupMetadataAPIResponse> responseObserver) {
-        super.deleteGroup(request, responseObserver);
+    public void deleteGroup(GroupMetadataAPIRequest request,
+                            StreamObserver<GroupMetadataAPIResponse> responseObserver) {
+        try {
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while deleting group " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(new Exception(msg));
+        }
     }
 
     @Override
-    public void createGroupMemberships(GroupMembershipAPIRequest request, StreamObserver<GroupMetadataAPIResponse> responseObserver) {
-        super.createGroupMemberships(request, responseObserver);
+    public void createGroupMemberships(GroupMembershipAPIRequest request,
+                                       StreamObserver<GroupMetadataAPIResponse> responseObserver) {
+        try {
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while creating group memberships " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(new Exception(msg));
+        }
     }
 
     @Override
-    public void deleteGroupMemberships(GroupMembershipAPIRequest request, StreamObserver<GroupMetadataAPIResponse> responseObserver) {
-        super.deleteGroupMemberships(request, responseObserver);
+    public void deleteGroupMemberships(GroupMembershipAPIRequest request,
+                                       StreamObserver<GroupMetadataAPIResponse> responseObserver) {
+        try {
+
+
+
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while deleting group memberships " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(new Exception(msg));
+        }
     }
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/ResourceServiceHandler.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/ResourceServiceHandler.java
index 1de7898..1009fb1 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/ResourceServiceHandler.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/ResourceServiceHandler.java
@@ -1,38 +1,125 @@
 package org.apache.airavata.datalake.metadata.handlers;
 
 import io.grpc.stub.StreamObserver;
+import org.apache.airavata.datalake.metadata.backend.Connector;
+import org.apache.airavata.datalake.metadata.backend.neo4j.curd.operators.ResourceServiceImpl;
+import org.apache.airavata.datalake.metadata.parsers.ResourceParser;
 import org.apache.airavata.datalake.metadata.service.*;
+import org.dozer.DozerBeanMapper;
 import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 
 @GRpcService
 public class ResourceServiceHandler extends ResourceMetadataServiceGrpc.ResourceMetadataServiceImplBase {
+    private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceHandler.class);
+    @Autowired
+    private DozerBeanMapper dozerBeanMapper;
+
+    @Autowired
+    private ResourceParser resourceParser;
+
+    @Autowired
+    private Connector connector;
+
+
     @Override
-    public void createResource(ResourceMetadataAPIRequest request, StreamObserver<ResourceMetadataAPIResponse> responseObserver) {
-        super.createResource(request, responseObserver);
+    public void createResource(ResourceMetadataAPIRequest request,
+                               StreamObserver<ResourceMetadataAPIResponse> responseObserver) {
+        try {
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while creating tenant " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(new Exception(msg));
+        }
+    }
+
+    @Override
+    public void getResource(ResourceMetadataAPIRequest request,
+                            StreamObserver<Resource> responseObserver) {
+        try {
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while fetching tenant " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(new Exception(msg));
+        }
     }
 
     @Override
-    public void getResource(ResourceMetadataAPIRequest request, StreamObserver<Resource> responseObserver) {
-        super.getResource(request, responseObserver);
+    public void updateResource(ResourceMetadataAPIRequest request,
+                               StreamObserver<ResourceMetadataAPIResponse> responseObserver) {
+        try {
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while updating tenant " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(new Exception(msg));
+        }
     }
 
     @Override
-    public void updateResource(ResourceMetadataAPIRequest request, StreamObserver<ResourceMetadataAPIResponse> responseObserver) {
-        super.updateResource(request, responseObserver);
+    public void deleteResource(ResourceMetadataAPIRequest request,
+                               StreamObserver<ResourceMetadataAPIResponse> responseObserver) {
+        try {
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while deleting tenant " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(new Exception(msg));
+        }
     }
 
     @Override
-    public void deleteResource(ResourceMetadataAPIRequest request, StreamObserver<ResourceMetadataAPIResponse> responseObserver) {
-        super.deleteResource(request, responseObserver);
+    public void shareResource(ResourceMetadataSharingRequest request,
+                              StreamObserver<ResourceMetadataAPIResponse> responseObserver) {
+        try {
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while sharing resource " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(new Exception(msg));
+        }
     }
 
     @Override
-    public void shareResource(ResourceMetadataSharingRequest request, StreamObserver<ResourceMetadataAPIResponse> responseObserver) {
-        super.shareResource(request, responseObserver);
+    public void deleteSharing(ResourceMetadataSharingRequest request,
+                              StreamObserver<ResourceMetadataAPIResponse> responseObserver) {
+        try {
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while delete sharing " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(new Exception(msg));
+        }
     }
 
     @Override
-    public void deleteSharing(ResourceMetadataSharingRequest request, StreamObserver<ResourceMetadataAPIResponse> responseObserver) {
-        super.deleteSharing(request, responseObserver);
+    public void hasAccess(ResourcePermissionRequest request,
+                          StreamObserver<ResourcePermissionResponse> responseObserver) {
+        try {
+            ResourceServiceImpl resourceService = new ResourceServiceImpl(connector);
+            boolean accessible = resourceService.hasAccess(request.getUsername(),
+                    request.getResourceName(), request.getPermissionType(),
+                    request.getTenantId());
+
+            ResourcePermissionResponse response = ResourcePermissionResponse
+                    .newBuilder()
+                    .setAccessible(accessible)
+                    .build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+        } catch (Exception ex) {
+
+        }
+
     }
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/TenantServiceHandler.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/TenantServiceHandler.java
index 66a2f42..aef3115 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/TenantServiceHandler.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/TenantServiceHandler.java
@@ -4,16 +4,16 @@ import io.grpc.stub.StreamObserver;
 import org.apache.airavata.datalake.metadata.backend.Connector;
 import org.apache.airavata.datalake.metadata.backend.neo4j.curd.operators.TenantServiceImpl;
 import org.apache.airavata.datalake.metadata.parsers.TenantParser;
-import org.apache.airavata.datalake.metadata.service.Tenant;
-import org.apache.airavata.datalake.metadata.service.TenantMetadataAPIRequest;
-import org.apache.airavata.datalake.metadata.service.TenantMetadataAPIResponse;
-import org.apache.airavata.datalake.metadata.service.TenantMetadataServiceGrpc;
+import org.apache.airavata.datalake.metadata.service.*;
 import org.dozer.DozerBeanMapper;
 import org.lognet.springboot.grpc.GRpcService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import java.util.List;
+import java.util.stream.Collectors;
+
 @GRpcService
 public class TenantServiceHandler extends TenantMetadataServiceGrpc.TenantMetadataServiceImplBase {
     private static final Logger LOGGER = LoggerFactory.getLogger(TenantServiceHandler.class);
@@ -27,14 +27,14 @@ public class TenantServiceHandler extends TenantMetadataServiceGrpc.TenantMetada
     @Autowired
     private Connector connector;
 
+
     @Override
     public void createTenant(TenantMetadataAPIRequest request,
                              StreamObserver<TenantMetadataAPIResponse> responseObserver) {
         try {
             Tenant tenant = request.getTenant();
             org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Tenant parsedTenant =
-                    (org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Tenant)
-                            tenantParser.parse(tenant);
+                    tenantParser.parse(tenant);
 
             TenantServiceImpl tenantService = new TenantServiceImpl(connector);
             tenantService.createOrUpdate(parsedTenant);
@@ -51,12 +51,31 @@ public class TenantServiceHandler extends TenantMetadataServiceGrpc.TenantMetada
 
     @Override
     public void getTenant(TenantMetadataAPIRequest request,
-                          StreamObserver<Tenant> responseObserver) {
+                          StreamObserver<FindTenantResponse> responseObserver) {
         try {
+            Tenant tenant = request.getTenant();
+            org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Tenant parsedTenant = tenantParser
+                    .parse(tenant);
 
+            TenantServiceImpl tenantService = new TenantServiceImpl(connector);
+            List<org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Tenant> tenantList =
+                    tenantService.find(parsedTenant);
 
-        } catch (Exception ex) {
+            if (tenantList.isEmpty()) {
+                responseObserver.onCompleted();
+            }
 
+            List<Tenant> tenants = tenantList.stream().map(t -> {
+                return tenantParser.parse(t);
+            }).collect(Collectors.toList());
+
+            FindTenantResponse response = FindTenantResponse.newBuilder().addAllTenants(tenants).build();
+            responseObserver.onNext(response);
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while fetching tenant " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(new Exception(msg));
         }
     }
 
@@ -65,9 +84,30 @@ public class TenantServiceHandler extends TenantMetadataServiceGrpc.TenantMetada
                              StreamObserver<TenantMetadataAPIResponse> responseObserver) {
         try {
 
+            TenantServiceImpl tenantService = new TenantServiceImpl(connector);
+            Tenant tenant = request.getTenant();
+            org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Tenant parsedTenant =
+                    tenantParser
+                            .parseAndMerge(tenant);
 
-        } catch (Exception ex) {
 
+            List<org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Tenant> tenantList =
+                    tenantService.find(parsedTenant);
+
+            if (tenantList.isEmpty()) {
+                responseObserver.onCompleted();
+            }
+
+            tenantService.createOrUpdate(parsedTenant);
+            TenantMetadataAPIResponse response = TenantMetadataAPIResponse.newBuilder().setStatus(true).build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while updating tenant " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(new Exception(msg));
         }
     }
 
@@ -75,10 +115,28 @@ public class TenantServiceHandler extends TenantMetadataServiceGrpc.TenantMetada
     public void deleteTenant(TenantMetadataAPIRequest request,
                              StreamObserver<TenantMetadataAPIResponse> responseObserver) {
         try {
+            Tenant tenant = request.getTenant();
+            org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Tenant parsedTenant = tenantParser
+                    .parse(tenant);
+
+            TenantServiceImpl tenantService = new TenantServiceImpl(connector);
+            List<org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Tenant> tenantList =
+                    tenantService.find(parsedTenant);
 
+            if (tenantList.isEmpty()) {
+                responseObserver.onCompleted();
+            }
 
-        } catch (Exception ex) {
+            tenantService.delete(tenantList.get(0).getId());
+            TenantMetadataAPIResponse response = TenantMetadataAPIResponse.newBuilder().setStatus(true).build();
+            responseObserver.onNext(response);
+            responseObserver.onCompleted();
 
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while deleting tenant " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(new Exception(msg));
         }
     }
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/UserServiceHandler.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/UserServiceHandler.java
index af2ceec..c4462c1 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/UserServiceHandler.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/handlers/UserServiceHandler.java
@@ -1,29 +1,67 @@
 package org.apache.airavata.datalake.metadata.handlers;
 
+import io.grpc.Status;
 import io.grpc.stub.StreamObserver;
-import org.apache.airavata.datalake.metadata.service.*;
+import org.apache.airavata.datalake.metadata.service.User;
+import org.apache.airavata.datalake.metadata.service.UserMetadataAPIRequest;
+import org.apache.airavata.datalake.metadata.service.UserMetadataAPIResponse;
+import org.apache.airavata.datalake.metadata.service.UserMetadataServiceGrpc;
 import org.lognet.springboot.grpc.GRpcService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 @GRpcService
 public class UserServiceHandler extends UserMetadataServiceGrpc.UserMetadataServiceImplBase {
+    private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceHandler.class);
+
     @Override
     public void createUser(UserMetadataAPIRequest request, StreamObserver<UserMetadataAPIResponse> responseObserver) {
-        super.createUser(request, responseObserver);
+        try {
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while creating user " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+
+        }
     }
 
     @Override
     public void getUser(UserMetadataAPIRequest request, StreamObserver<User> responseObserver) {
-        super.getUser(request, responseObserver);
+        try {
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while fetching user " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
     }
 
     @Override
     public void updateUser(UserMetadataAPIRequest request, StreamObserver<UserMetadataAPIResponse> responseObserver) {
-        super.updateUser(request, responseObserver);
+        try {
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while updating user " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
     }
 
     @Override
     public void deleteUser(UserMetadataAPIRequest request, StreamObserver<UserMetadataAPIResponse> responseObserver) {
-        super.deleteUser(request, responseObserver);
+        try {
+
+
+        } catch (Exception ex) {
+            String msg = "Exception occurred while deleting user " + ex;
+            LOGGER.error(msg);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
     }
 
+
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/interceptors/Authenticator.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/interceptors/Authenticator.java
new file mode 100644
index 0000000..2eeaa0e
--- /dev/null
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/interceptors/Authenticator.java
@@ -0,0 +1,19 @@
+package org.apache.airavata.datalake.metadata.interceptors;
+
+import io.grpc.Metadata;
+import org.apache.airavata.datalake.metadata.AppConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class Authenticator implements ServiceInterceptor {
+    private static final Logger LOGGER = LoggerFactory.getLogger(AppConfig.class);
+
+    @Override
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) {
+        LOGGER.info("Calling interceptor #######");
+        return msg;
+    }
+
+}
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/interceptors/InterceptorPipelineExecutor.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/interceptors/InterceptorPipelineExecutor.java
new file mode 100644
index 0000000..7e0e72a
--- /dev/null
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/interceptors/InterceptorPipelineExecutor.java
@@ -0,0 +1,69 @@
+package org.apache.airavata.datalake.metadata.interceptors;
+
+import io.grpc.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Iterator;
+import java.util.Stack;
+
+/**
+ * This class execute interceptor stack sequentially
+ */
+
+public class InterceptorPipelineExecutor implements ServerInterceptor {
+    private final Logger LOGGER = LoggerFactory.getLogger(InterceptorPipelineExecutor.class);
+
+    private Stack<ServiceInterceptor> interceptorSet;
+
+    public InterceptorPipelineExecutor(Stack<ServiceInterceptor> integrationServiceInterceptors) {
+        this.interceptorSet = integrationServiceInterceptors;
+    }
+
+    @Override
+    public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> serverCall,
+                                                                 Metadata metadata, ServerCallHandler<ReqT, RespT> serverCallHandler) {
+        String fullMethod = serverCall.getMethodDescriptor().getFullMethodName();
+        String methodName = fullMethod.split("/")[1];
+        String serviceName = fullMethod.split("/")[0];
+
+        LOGGER.debug("Calling method : " + serverCall.getMethodDescriptor().getFullMethodName());
+        metadata.put(Metadata.Key.of("service-name", Metadata.ASCII_STRING_MARSHALLER), serviceName);
+
+        return new ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>(serverCallHandler.startCall(serverCall, metadata)) {
+
+            ReqT resp = null;
+
+            @Override
+            public void onMessage(ReqT message) {
+                try {
+                    Iterator it = interceptorSet.iterator();
+                    while (it.hasNext()) {
+                        ServiceInterceptor interceptor = (ServiceInterceptor) it.next();
+                        resp = interceptor.intercept(methodName, metadata, (resp == null) ? message : resp);
+                    }
+                    super.onMessage(resp);
+                } catch (Exception ex) {
+                    String msg = "Error while validating method " + methodName + ", " + ex.getMessage();
+                    LOGGER.error(msg, ex);
+                    serverCall.close(Status.INVALID_ARGUMENT.withDescription(msg), new Metadata());
+                }
+            }
+
+            @Override
+            public void onHalfClose() {
+                try {
+                    super.onHalfClose();
+                } catch (IllegalStateException e) {
+                    LOGGER.debug(e.getMessage());
+                } catch (Exception e) {
+                    String msg = "Error while validating method " + methodName + ", " + e.getMessage();
+                    LOGGER.error(msg);
+                    serverCall.close(Status.INVALID_ARGUMENT.withDescription(msg), metadata);
+                }
+            }
+
+        };
+
+    }
+}
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/interceptors/ServiceInterceptor.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/interceptors/ServiceInterceptor.java
new file mode 100644
index 0000000..ba05742
--- /dev/null
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/interceptors/ServiceInterceptor.java
@@ -0,0 +1,7 @@
+package org.apache.airavata.datalake.metadata.interceptors;
+
+import io.grpc.Metadata;
+
+public interface ServiceInterceptor {
+    public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg);
+}
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/mergers/GenericMerger.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/mergers/GenericMerger.java
new file mode 100644
index 0000000..c3a003c
--- /dev/null
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/mergers/GenericMerger.java
@@ -0,0 +1,46 @@
+package org.apache.airavata.datalake.metadata.mergers;
+
+import org.apache.airavata.datalake.metadata.backend.Connector;
+import org.apache.airavata.datalake.metadata.backend.neo4j.curd.operators.*;
+import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.*;
+import org.apache.airavata.datalake.metadata.parsers.ExecutionContext;
+
+import java.util.List;
+
+
+public class GenericMerger implements Merger {
+
+    private static Connector connector;
+
+    public GenericMerger(Connector connector) {
+        this.connector = connector;
+    }
+
+    @Override
+    public Entity merge(Entity entity) {
+        ExecutionContext executionContext = entity.getExecutionContext();
+        executionContext.getNeo4JConvertedModels().values().forEach(en -> {
+            List<Entity> entityList = genericService((Entity) en).find(en);
+            if (!entityList.isEmpty()) {
+                Entity exEnt = entityList.get(0);
+                ((Entity) en).setId(exEnt.getId());
+            }
+        });
+        return entity;
+    }
+
+    public static GenericService genericService(Entity entity) {
+        if (entity instanceof Tenant) {
+            return new TenantServiceImpl(connector);
+        } else if (entity instanceof Resource) {
+            return new ResourceServiceImpl(connector);
+        } else if (entity instanceof Group) {
+            return new GroupServiceImpl(connector);
+        } else if (entity instanceof User) {
+            return new UserServiceImpl(connector);
+        }
+        return null;
+    }
+
+
+}
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/mergers/Merger.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/mergers/Merger.java
new file mode 100644
index 0000000..d63b2f1
--- /dev/null
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/mergers/Merger.java
@@ -0,0 +1,9 @@
+package org.apache.airavata.datalake.metadata.mergers;
+
+import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Entity;
+
+public interface Merger {
+
+    public Entity merge(Entity entity);
+
+}
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/ExecutionContext.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/ExecutionContext.java
index 0a8365a..e468237 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/ExecutionContext.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/ExecutionContext.java
@@ -14,4 +14,8 @@ public class ExecutionContext {
     public void addNeo4JConvertedModels(String key, Object obj) {
         this.neo4JConvertedModels.put(key, obj);
     }
+
+    public Map<String, Object> getNeo4JConvertedModels() {
+        return neo4JConvertedModels;
+    }
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/GroupParser.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/GroupParser.java
index f486841..06fd918 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/GroupParser.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/GroupParser.java
@@ -4,6 +4,7 @@ import com.google.protobuf.GeneratedMessageV3;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Entity;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Group;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.User;
+import org.apache.airavata.datalake.metadata.mergers.Merger;
 import org.apache.airavata.datalake.metadata.service.GroupMembership;
 import org.dozer.DozerBeanMapper;
 import org.slf4j.Logger;
@@ -22,7 +23,7 @@ public class GroupParser implements Parser {
 
 
     @Override
-    public Entity parse(GeneratedMessageV3 entity, Entity parentEntity, ExecutionContext executionContext) {
+    public Group parse(GeneratedMessageV3 entity, Entity parentEntity, ExecutionContext executionContext, Merger merger) {
         if (entity instanceof org.apache.airavata.datalake.metadata.service.Group) {
             org.apache.airavata.datalake.metadata.service.Group group = (org.apache.airavata.datalake.metadata.service.Group) entity;
             Group newParentGroup = null;
@@ -31,6 +32,7 @@ public class GroupParser implements Parser {
                         org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Group.class);
                 LOGGER.info("Creating group "+ newParentGroup.getName() + " class"+ newParentGroup.toString());
                 executionContext.addNeo4JConvertedModels(newParentGroup.getSearchableId(),newParentGroup);
+                newParentGroup.setExecutionContext(executionContext);
             } else if (parentEntity != null){
                 newParentGroup = (Group) parentEntity;
                 Group childGroup = dozerBeanMapper.map(group,
@@ -41,7 +43,7 @@ public class GroupParser implements Parser {
                         childGroup.getCreatedAt() != 0 ? childGroup.getCreatedAt() : System.currentTimeMillis(),
                         childGroup.getLastModifiedAt() != 0 ? childGroup.getLastModifiedAt() : System.currentTimeMillis(),
                         null); // Improve this with relatioship propertie
-
+                childGroup.setExecutionContext(executionContext);
                 newParentGroup = childGroup;
             }
 
@@ -66,7 +68,7 @@ public class GroupParser implements Parser {
 
                 Group finalNewParentGroup = newParentGroup;
                 groups.forEach(gr -> {
-                    this.parse(gr, finalNewParentGroup, executionContext);
+                    this.parse(gr, finalNewParentGroup, executionContext,merger);
                 });
             }
 
@@ -80,11 +82,16 @@ public class GroupParser implements Parser {
 
     @Override
     public Entity parse(GeneratedMessageV3 entity, ExecutionContext executionContext) {
-        return this.parse(entity,null, executionContext);
+        return this.parse(entity,null, executionContext,null);
     }
 
     @Override
     public Entity parse(GeneratedMessageV3 entity) {
-        return this.parse(entity,null,new ExecutionContext());
+        return this.parse(entity,null,new ExecutionContext(),null);
+    }
+
+    @Override
+    public Entity parseAndMerge(GeneratedMessageV3 entity) {
+        return null;
     }
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/Parser.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/Parser.java
index 9ed0683..2ce567b 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/Parser.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/Parser.java
@@ -2,12 +2,15 @@ package org.apache.airavata.datalake.metadata.parsers;
 
 import com.google.protobuf.GeneratedMessageV3;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Entity;
+import org.apache.airavata.datalake.metadata.mergers.Merger;
 
 public interface Parser {
 
-    public Entity parse(GeneratedMessageV3 entity, Entity parentEntity, ExecutionContext executionContext);
+    public Entity parse(GeneratedMessageV3 entity, Entity parentEntity, ExecutionContext executionContext, Merger merger);
 
     public Entity parse(GeneratedMessageV3 entity, ExecutionContext executionContext);
 
     public Entity parse(GeneratedMessageV3 entity);
+
+    public Entity parseAndMerge(GeneratedMessageV3 entity);
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/ResourceParser.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/ResourceParser.java
index 29a7a95..565aa6d 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/ResourceParser.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/ResourceParser.java
@@ -5,6 +5,7 @@ import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Entity;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Group;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Resource;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.User;
+import org.apache.airavata.datalake.metadata.mergers.Merger;
 import org.apache.airavata.datalake.metadata.service.ResourceSharings;
 import org.dozer.DozerBeanMapper;
 import org.slf4j.Logger;
@@ -29,7 +30,7 @@ public class ResourceParser implements Parser {
 
 
     @Override
-    public Entity parse(GeneratedMessageV3 entity, Entity parentEntity, ExecutionContext executionContext) {
+    public Resource parse(GeneratedMessageV3 entity, Entity parentEntity, ExecutionContext executionContext, Merger merger) {
         if (entity instanceof org.apache.airavata.datalake.metadata.service.Resource) {
             org.apache.airavata.datalake.metadata.service.Resource resource =
                     (org.apache.airavata.datalake.metadata.service.Resource) entity;
@@ -39,15 +40,19 @@ public class ResourceParser implements Parser {
                 newParentResource = dozerBeanMapper.map(resource,
                         org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Resource.class);
                 executionContext.addNeo4JConvertedModels(newParentResource.getSearchableId(), newParentResource);
+                newParentResource.setExecutionContext(executionContext);
             } else {
                 newParentResource = (Resource) parentEntity;
+
                 Resource childResource = dozerBeanMapper.map(resource,
                         org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Resource.class);
                 executionContext.addNeo4JConvertedModels(newParentResource.getSearchableId(), newParentResource);
+
                 newParentResource.addChildResource(childResource,
                         childResource.getCreatedAt() != 0 ? childResource.getCreatedAt() : System.currentTimeMillis(),
                         childResource.getLastModifiedAt() != 0 ? childResource.getLastModifiedAt() : System.currentTimeMillis(),
-                        null); // Improve this with relatioship properties
+                        null); // Improve this with relationship properties
+                childResource.setExecutionContext(executionContext);
                 newParentResource = childResource;
             }
 
@@ -102,7 +107,7 @@ public class ResourceParser implements Parser {
             if (!resources.isEmpty()) {
                 Resource finalNewParentResource = newParentResource;
                 resources.forEach(gr -> {
-                    this.parse(gr, finalNewParentResource, executionContext);
+                    this.parse(gr, finalNewParentResource, executionContext, merger);
                 });
             }
             return newParentResource;
@@ -115,11 +120,16 @@ public class ResourceParser implements Parser {
 
     @Override
     public Entity parse(GeneratedMessageV3 entity, ExecutionContext executionContext) {
-        return this.parse(entity, null, executionContext);
+        return this.parse(entity, null, executionContext, null);
     }
 
     @Override
     public Entity parse(GeneratedMessageV3 entity) {
-        return this.parse(entity, null, new ExecutionContext());
+        return this.parse(entity, null, new ExecutionContext(),null);
+    }
+
+    @Override
+    public Entity parseAndMerge(GeneratedMessageV3 entity) {
+        return null;
     }
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/TenantParser.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/TenantParser.java
index efba859..796273b 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/TenantParser.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/TenantParser.java
@@ -1,7 +1,11 @@
 package org.apache.airavata.datalake.metadata.parsers;
 
 import com.google.protobuf.GeneratedMessageV3;
+import org.apache.airavata.datalake.metadata.backend.Connector;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Entity;
+import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Tenant;
+import org.apache.airavata.datalake.metadata.mergers.GenericMerger;
+import org.apache.airavata.datalake.metadata.mergers.Merger;
 import org.apache.airavata.datalake.metadata.service.Group;
 import org.apache.airavata.datalake.metadata.service.Resource;
 import org.apache.airavata.datalake.metadata.service.User;
@@ -29,8 +33,12 @@ public class TenantParser implements Parser {
     @Autowired
     private ResourceParser resourceParser;
 
+    @Autowired
+    private Connector connector;
+
+
     @Override
-    public Entity parse(GeneratedMessageV3 entity, Entity parentEntity, ExecutionContext executionContext) {
+    public Tenant parse(GeneratedMessageV3 entity, Entity parentEntity, ExecutionContext executionContext, Merger merger) {
         if (entity instanceof org.apache.airavata.datalake.metadata.service.Tenant) {
 
             org.apache.airavata.datalake.metadata.service.Tenant tenant =
@@ -44,14 +52,14 @@ public class TenantParser implements Parser {
                     dozerBeanMapper.map(tenant,
                             org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Tenant.class);
             neo4JTenant.setPrimaryExternalKey(neo4JTenant.getTenantId());
-            executionContext.addNeo4JConvertedModels(neo4JTenant.getSearchableId(),neo4JTenant);
+            neo4JTenant.setExecutionContext(executionContext);
+            executionContext.addNeo4JConvertedModels(neo4JTenant.getSearchableId(), neo4JTenant);
 
             if (!groups.isEmpty()) {
                 groups.stream().forEach(group -> {
                     org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Group neo4JGr =
-                            (org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Group)
-                                    groupParser.parse(group, null, executionContext);
-                    executionContext.addNeo4JConvertedModels(neo4JGr.getSearchableId(),neo4JGr);
+                            groupParser.parse(group, null, executionContext, merger);
+                    executionContext.addNeo4JConvertedModels(neo4JGr.getSearchableId(), neo4JGr);
                     neo4JTenant.add(neo4JGr, tenant.getCreatedAt() != 0 ? tenant.getCreatedAt() : System.currentTimeMillis(),
                             tenant.getLastModifiedAt() != 0 ? tenant.getLastModifiedAt() : System.currentTimeMillis(),
                             null);
@@ -61,9 +69,8 @@ public class TenantParser implements Parser {
             if (!users.isEmpty()) {
                 users.stream().forEach(user -> {
                     org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.User usr =
-                            (org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.User)
-                                    userParser.parse(user, null, executionContext);
-                    executionContext.addNeo4JConvertedModels(usr.getSearchableId(),usr);
+                            userParser.parse(user, null, executionContext, merger);
+                    executionContext.addNeo4JConvertedModels(usr.getSearchableId(), usr);
                     neo4JTenant.add(usr, tenant.getCreatedAt() != 0 ? tenant.getCreatedAt() : System.currentTimeMillis(),
                             tenant.getLastModifiedAt() != 0 ? tenant.getLastModifiedAt() : System.currentTimeMillis(),
                             null);
@@ -73,14 +80,16 @@ public class TenantParser implements Parser {
             if (!resources.isEmpty()) {
                 resources.stream().forEach(resource -> {
                     org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Resource neo4JResource =
-                            (org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Resource)
-                                    resourceParser.parse(resource, null, executionContext);
-                    executionContext.addNeo4JConvertedModels(neo4JResource.getSearchableId(),neo4JResource);
+                            resourceParser.parse(resource, null, executionContext, merger);
+                    executionContext.addNeo4JConvertedModels(neo4JResource.getSearchableId(), neo4JResource);
                     neo4JTenant.add(neo4JResource, tenant.getCreatedAt() != 0 ? tenant.getCreatedAt() : System.currentTimeMillis(),
                             tenant.getLastModifiedAt() != 0 ? tenant.getLastModifiedAt() : System.currentTimeMillis(),
                             null);
                 });
             }
+            if (merger != null) {
+                merger.merge(neo4JTenant);
+            }
             return neo4JTenant;
         } else {
             String msg = "Wrong entity type detected for parser Tenant Parser, Expected Tenant";
@@ -90,12 +99,25 @@ public class TenantParser implements Parser {
     }
 
     @Override
-    public Entity parse(GeneratedMessageV3 entity, ExecutionContext executionContext) {
-        return this.parse(entity, null, executionContext);
+    public Tenant parse(GeneratedMessageV3 entity, ExecutionContext executionContext) {
+        return this.parse(entity, null, executionContext, null);
     }
 
     @Override
-    public Entity parse(GeneratedMessageV3 entity) {
-        return this.parse(entity, null, new ExecutionContext());
+    public Tenant parse(GeneratedMessageV3 entity) {
+        return this.parse(entity, null, new ExecutionContext(), null);
     }
+
+    @Override
+    public Tenant parseAndMerge(GeneratedMessageV3 entity) {
+        return this.parse(entity, null, new ExecutionContext(), new GenericMerger(connector));
+    }
+
+    public org.apache.airavata.datalake.metadata.service.Tenant parse(Tenant tenant) {
+        Object obj = dozerBeanMapper.
+                map(tenant, org.apache.airavata.datalake.metadata.service.Tenant.newBuilder().getClass());
+        return (org.apache.airavata.datalake.metadata.service.Tenant) obj;
+
+    }
+
 }
diff --git a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/UserParser.java b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/UserParser.java
index 371c316..dbd8b91 100644
--- a/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/UserParser.java
+++ b/metadata-service/db-service/server/src/main/java/org/apache/airavata/datalake/metadata/parsers/UserParser.java
@@ -2,6 +2,8 @@ package org.apache.airavata.datalake.metadata.parsers;
 
 import com.google.protobuf.GeneratedMessageV3;
 import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.Entity;
+import org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.User;
+import org.apache.airavata.datalake.metadata.mergers.Merger;
 import org.dozer.DozerBeanMapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -18,12 +20,15 @@ public class UserParser implements Parser {
 
 
     @Override
-    public Entity parse(GeneratedMessageV3 entity, Entity parentEntity, ExecutionContext executionContext) {
+    public User parse(GeneratedMessageV3 entity, Entity parentEntity, ExecutionContext executionContext, Merger merger) {
         if (entity instanceof org.apache.airavata.datalake.metadata.service.User) {
             org.apache.airavata.datalake.metadata.service.User user =
                     (org.apache.airavata.datalake.metadata.service.User) entity;
-            return dozerBeanMapper.map(user,
+            User usr = (User) dozerBeanMapper.map(user,
                     org.apache.airavata.datalake.metadata.backend.neo4j.model.nodes.User.class);
+            executionContext.addNeo4JConvertedModels(usr.getSearchableId(), usr);
+            usr.setExecutionContext(executionContext);
+            return usr;
         } else {
             String msg = "Wrong entity type detected for parser User Parser, Expected User";
             LOGGER.error(msg);
@@ -33,11 +38,16 @@ public class UserParser implements Parser {
 
     @Override
     public Entity parse(GeneratedMessageV3 entity, ExecutionContext executionContext) {
-        return this.parse(entity, null, executionContext);
+        return this.parse(entity, null, executionContext,null);
     }
 
     @Override
     public Entity parse(GeneratedMessageV3 entity) {
-        return this.parse(entity, null, new ExecutionContext());
+        return this.parse(entity, null, new ExecutionContext(),null);
+    }
+
+    @Override
+    public Entity parseAndMerge(GeneratedMessageV3 entity) {
+        return null;
     }
 }
diff --git a/metadata-service/db-service/stub/src/main/proto/resource/Resource.proto b/metadata-service/db-service/stub/src/main/proto/resource/Resource.proto
index ce52a04..7e52cb9 100644
--- a/metadata-service/db-service/stub/src/main/proto/resource/Resource.proto
+++ b/metadata-service/db-service/stub/src/main/proto/resource/Resource.proto
@@ -26,6 +26,20 @@ message ResourceMetadataAPIResponse {
     bool status = 1;
 }
 
+message ResourcePermissionRequest {
+    string username = 1;
+    string groupname = 2;
+    string permission_type = 3;
+    string tenant_id = 4;
+    string resource_name = 5;
+    map<string, string> resource_properties = 6;
+}
+
+message ResourcePermissionResponse {
+   bool accessible = 1;
+}
+
+
 
 message Resource {
     string tenant_id = 1;
@@ -95,4 +109,10 @@ service ResourceMetadataService {
         };
     }
 
+    rpc hasAccess (ResourcePermissionRequest) returns (ResourcePermissionResponse) {
+        option (google.api.http) = {
+           get: "/v1.0/api/metadata/resource/permission"
+        };
+    }
+
 }
\ No newline at end of file
diff --git a/metadata-service/db-service/stub/src/main/proto/tenant/Tenant.proto b/metadata-service/db-service/stub/src/main/proto/tenant/Tenant.proto
index d0063ea..c1c59a4 100644
--- a/metadata-service/db-service/stub/src/main/proto/tenant/Tenant.proto
+++ b/metadata-service/db-service/stub/src/main/proto/tenant/Tenant.proto
@@ -37,6 +37,10 @@ message Tenant {
 
 }
 
+message FindTenantResponse {
+    repeated Tenant tenants = 1;
+}
+
 
 service TenantMetadataService {
 
@@ -46,7 +50,7 @@ service TenantMetadataService {
         };
     }
 
-    rpc getTenant (TenantMetadataAPIRequest) returns (Tenant) {
+    rpc getTenant (TenantMetadataAPIRequest) returns (FindTenantResponse) {
         option (google.api.http) = {
            get: "/v1.0/api/metadata/tenant"
         };