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/30 12:50:17 UTC

[airavata-data-lake] branch master updated: DRMS API IMplementations

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


The following commit(s) were added to refs/heads/master by this push:
     new 4bb34b5  DRMS API IMplementations
     new 7400986  Merge pull request #9 from isururanawaka/workflow_merge
4bb34b5 is described below

commit 4bb34b586e3b7c766242f637d789a6ff23f7bc7e
Author: Isuru Ranawaka <ir...@gmail.com>
AuthorDate: Tue Jun 29 23:20:43 2021 -0400

    DRMS API IMplementations
---
 data-resource-management-service/drms-api/pom.xml  |  20 ++
 .../java/org/apache/airavata/drms/api/Client.java  | 125 ++++++-
 .../drms/api/handlers/ResourceServiceHandler.java  | 400 +++++++++++++++++++--
 .../drms/api/interceptors/Authenticator.java       |  34 +-
 .../airavata/drms/api/utils/CustosUtils.java       |  35 ++
 .../org/apache/airavata/drms/api/utils/Utils.java  |   1 +
 .../apache/airavata/drms/core/Neo4JConnector.java  |   2 +-
 .../deserializer/GenericResourceDeserializer.java  |   3 +
 .../core/serializer/GenericResourceSerializer.java |  28 ++
 .../custos/synchronizer/CustosSynchronizer.java    |   5 +-
 .../drms-rest-proxy/src/main/resources/drms.pb     | Bin 104720 -> 107086 bytes
 .../drms-rest-proxy/src/main/resources/envoy.yaml  |   2 +-
 .../src/main/resources/generator.txt               |   1 +
 .../drms-stubs/drms.pb                             | Bin 104720 -> 0 bytes
 .../src/main/proto/resource/DRMSResource.proto     |   2 +
 .../main/proto/resource/DRMSResourceService.proto  |  90 ++++-
 16 files changed, 679 insertions(+), 69 deletions(-)

diff --git a/data-resource-management-service/drms-api/pom.xml b/data-resource-management-service/drms-api/pom.xml
index 227b4ac..6068140 100644
--- a/data-resource-management-service/drms-api/pom.xml
+++ b/data-resource-management-service/drms-api/pom.xml
@@ -76,4 +76,24 @@
         </dependency>
 
     </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <fork>true</fork>
+                    <mainClass>org.apache.airavata.drms.api.DRMSApiRunner</mainClass>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
\ No newline at end of file
diff --git a/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/Client.java b/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/Client.java
index 5032c09..4ccdc8e 100644
--- a/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/Client.java
+++ b/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/Client.java
@@ -20,13 +20,17 @@ import com.google.protobuf.Struct;
 import io.grpc.ManagedChannel;
 import io.grpc.ManagedChannelBuilder;
 import org.apache.airavata.datalake.drms.DRMSServiceAuthToken;
-import org.apache.airavata.datalake.drms.storage.StoragePreferenceFetchRequest;
-import org.apache.airavata.datalake.drms.storage.StoragePreferenceFetchResponse;
+import org.apache.airavata.datalake.drms.resource.GenericResource;
+import org.apache.airavata.datalake.drms.storage.ParentResourcesFetchRequest;
+import org.apache.airavata.datalake.drms.storage.ResourceServiceGrpc;
 import org.apache.airavata.datalake.drms.storage.StoragePreferenceServiceGrpc;
 import org.apache.airavata.datalake.drms.storage.StorageServiceGrpc;
 import org.apache.custos.clients.CustosClientProvider;
 import org.apache.custos.identity.management.client.IdentityManagementClient;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class Client {
     public static void main(String ar[]) {
 
@@ -76,14 +80,14 @@ public class Client {
 //        storagePreferenceServiceBlockingStub.searchStoragePreference(storagePreferenceSearchRequest);
 
 
-        StoragePreferenceFetchRequest storagePreferenceSearchRequest = StoragePreferenceFetchRequest
-                .newBuilder()
-                .setAuthToken(authToken)
-                .setStoragePreferenceId("storage-preference-id-one")
-                .build();
-      StoragePreferenceFetchResponse response =   storagePreferenceServiceBlockingStub
-              .fetchStoragePreference(storagePreferenceSearchRequest);
-        System.out.println(response.getStoragePreference().getSshStoragePreference().getUserName());
+//        StoragePreferenceFetchRequest storagePreferenceSearchRequest = StoragePreferenceFetchRequest
+//                .newBuilder()
+//                .setAuthToken(authToken)
+//                .setStoragePreferenceId("storage-preference-id-one")
+//                .build();
+//      StoragePreferenceFetchResponse response =   storagePreferenceServiceBlockingStub
+//              .fetchStoragePreference(storagePreferenceSearchRequest);
+//        System.out.println(response.getStoragePreference().getSshStoragePreference().getUserName());
 
 
 //        StoragePreferenceCreateRequest storagePreferenceCreateRequest = StoragePreferenceCreateRequest
@@ -105,10 +109,103 @@ public class Client {
 //        storagePreferenceServiceBlockingStub.createStoragePreference(storagePreferenceCreateRequest);
 
 
+        ResourceServiceGrpc.ResourceServiceBlockingStub resourceServiceBlockingStub = ResourceServiceGrpc.newBlockingStub(channel);
+
+//        ResourceSearchQuery query = ResourceSearchQuery.newBuilder().setField("type").setValue("COLLECTION").build();
+//
+//        ResourceSearchRequest request = ResourceSearchRequest
+//                .newBuilder()
+//                .setAuthToken(authToken)
+//                .addQueries(query).build();
+//
+//        ResourceSearchResponse response =   resourceServiceBlockingStub.searchResource(request);
+//        response.getResourcesList();
+
+//        ChildResourceFetchRequest childResourceFetchRequest = ChildResourceFetchRequest
+//                .newBuilder()
+//                .setAuthToken(authToken)
+//                .setResourceId("COLLECTION_TWO_a1qeBCVSrpx8vLJ")
+//                .setDepth(1)
+//                .setType("COLLECTION")
+//                .build();
+//
+//        resourceServiceBlockingStub.fetchChildResources(childResourceFetchRequest);
+
+//        String id = UUID.randomUUID().toString();
+//
+//        GenericResource genericResource = GenericResource
+//                .newBuilder()
+//                .setResourceId(id)
+//                .setType("COLLECTION")
+//                .setResourceName("COLLECTION_SDK_TEST_TWO")
+//                .build();
+//
+//        ResourceCreateRequest resourceCreateRequest = ResourceCreateRequest.newBuilder()
+//                .setAuthToken(authToken)
+//                .setResource(genericResource)
+//                .build();
+//        resourceServiceBlockingStub.createResource(resourceCreateRequest);
+
+
+//        System.out.println(authToken.getAccessToken());
+//        ResourceFetchRequest resourceFetchRequest = ResourceFetchRequest.newBuilder()
+//                .setAuthToken(authToken)
+//                .setResourceId("COLLECTION_ONE_6kKQzhIt8zxvIgn")
+//                .setType("COLLECTION")
+//                .build();
+//
+//        resourceServiceBlockingStub.fetchResource(resourceFetchRequest);
+
+        GenericResource parentResource = GenericResource.newBuilder()
+                .setResourceId("56cec8a2-a2c2-4669-9274-a5b5bdd97c11")
+                .setType("COLLECTION")
+                .build();
+
+        GenericResource childResource = GenericResource.newBuilder()
+                .setResourceId("b75b4cec-8df4-4f99-9d06-818db285cf02")
+                .setType("COLLECTION")
+                .build();
+
+        GenericResource childResource1 = GenericResource.newBuilder()
+                .setResourceId("b7ee2fd5-c4b8-4bb9-896b-4cb98d91ad24")
+                .setType("COLLECTION")
+                .build();
+
+        List<GenericResource> genericResourceList = new ArrayList<>();
+        genericResourceList.add(childResource);
+        genericResourceList.add(childResource1);
+
+//        AddChildResourcesMembershipRequest addChildResourcesMembershipRequest = AddChildResourcesMembershipRequest
+//                .newBuilder()
+//                .setParentResource(parentResource)
+//                .addAllChildResources(genericResourceList)
+//                .setAuthToken(authToken)
+//                .build();
+//        resourceServiceBlockingStub.addChildMembership(addChildResourcesMembershipRequest);
+
+
+//        DeleteChildResourcesMembershipRequest deleteChildResourcesMembershipRequest = DeleteChildResourcesMembershipRequest
+//                .newBuilder()
+//                .setParentResource(parentResource)
+//                .addAllChildResources(genericResourceList)
+//                .setAuthToken(authToken)
+//                .build();
+//        resourceServiceBlockingStub.deleteChildMembership(deleteChildResourcesMembershipRequest);
+
+        ParentResourcesFetchRequest parentResourcesFetchRequest = ParentResourcesFetchRequest
+                .newBuilder()
+                .setAuthToken(authToken)
+                .setResourceId("FILE_ONE_bxZPopxbnPaAEq5")
+                .setType("FILE")
+                .setDepth(2)
+                .build();
+        resourceServiceBlockingStub.fetchParentResources(parentResourcesFetchRequest);
+
+
     }
 
 
-    private static String getAccessToken(){
+    private static String getAccessToken() {
         try {
 
             CustosClientProvider custosClientProvider = new CustosClientProvider.Builder().setServerHost("custos.scigap.org")
@@ -119,9 +216,9 @@ public class Client {
             IdentityManagementClient identityManagementClient = custosClientProvider.getIdentityManagementClient();
             Struct struct = identityManagementClient.getToken(null, null, "testuser", "testuser1234", null, "password");
             return struct.getFieldsMap().get("access_token").getStringValue();
-        }catch (Exception ex){
-ex.printStackTrace();
+        } catch (Exception ex) {
+            ex.printStackTrace();
         }
-       return null;
+        return null;
     }
 }
diff --git a/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/handlers/ResourceServiceHandler.java b/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/handlers/ResourceServiceHandler.java
index ff77b68..9c746fd 100644
--- a/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/handlers/ResourceServiceHandler.java
+++ b/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/handlers/ResourceServiceHandler.java
@@ -17,21 +17,28 @@
 package org.apache.airavata.drms.api.handlers;
 
 import com.google.protobuf.Empty;
+import io.grpc.Status;
 import io.grpc.stub.StreamObserver;
 import org.apache.airavata.datalake.drms.AuthenticatedUser;
 import org.apache.airavata.datalake.drms.resource.GenericResource;
 import org.apache.airavata.datalake.drms.storage.*;
+import org.apache.airavata.drms.api.utils.CustosUtils;
 import org.apache.airavata.drms.core.Neo4JConnector;
 import org.apache.airavata.drms.core.constants.ResourceConstants;
+import org.apache.airavata.drms.core.constants.StoragePreferenceConstants;
 import org.apache.airavata.drms.core.deserializer.GenericResourceDeserializer;
 import org.apache.airavata.drms.core.deserializer.MetadataDeserializer;
+import org.apache.airavata.drms.core.serializer.GenericResourceSerializer;
+import org.apache.custos.clients.CustosClientProvider;
+import org.apache.custos.sharing.service.Entity;
 import org.lognet.springboot.grpc.GRpcService;
 import org.neo4j.driver.Record;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 
-import java.util.List;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
 
 @GRpcService
 public class ResourceServiceHandler extends ResourceServiceGrpc.ResourceServiceImplBase {
@@ -41,39 +48,168 @@ public class ResourceServiceHandler extends ResourceServiceGrpc.ResourceServiceI
     @Autowired
     private Neo4JConnector neo4JConnector;
 
+    @Autowired
+    private CustosClientProvider custosClientProvider;
+
     @Override
     public void fetchResource(ResourceFetchRequest request, StreamObserver<ResourceFetchResponse> responseObserver) {
-//        User callUser = getUser(request.getAuthToken());
 
-        AuthenticatedUser callUser = request.getAuthToken().getAuthenticatedUser();
+        try {
+            AuthenticatedUser callUser = request.getAuthToken().getAuthenticatedUser();
+
+            String resourceId = request.getResourceId();
+            String type = request.getType();
+
+            Map<String, Object> userProps = new HashMap<>();
+            userProps.put("username", callUser.getUsername());
+            userProps.put("tenantId", callUser.getTenantId());
+            userProps.put("entityId", resourceId);
+
+            String query = " MATCH (u:User),  (r:" + type + ") where u.username = $username AND u.tenantId = $tenantId AND " +
+                    " r.entityId = $entityId AND r.tenantId = $tenantId" +
+                    " OPTIONAL MATCH (cg:Group)-[:CHILD_OF*]->(g:Group)<-[:MEMBER_OF]-(u)" +
+                    " return case when  exists((u)<-[:SHARED_WITH]-(r)) OR  exists((g)<-[:SHARED_WITH]-(r)) OR   " +
+                    "exists((cg)<-[:SHARED_WITH]-(r)) then r  else NULL end as value";
 
-        // TODO review (u)-[r4:MEMBER_OF]->(g2:Group)<-[r5:SHARED_WITH]-(sp),
-        List<Record> records = this.neo4JConnector.searchNodes(
-                "MATCH (u:User)-[r1:MEMBER_OF]->(g:Group)<-[r2:SHARED_WITH]-(s:Storage)-[r3:HAS_PREFERENCE]->(sp:StoragePreference)-[r6:HAS_RESOURCE]->(res:Resource), " +
-                        "(u)-[r7:MEMBER_OF]->(g3:Group)<-[r8:SHARED_WITH]-(res) " +
-                        "where res.resourceId = '" + request.getResourceId() + "' and u.userId = '"
-                        + callUser.getUsername() + "' return distinct res, sp, s");
 
-        if (!records.isEmpty()) {
+            List<Record> records = this.neo4JConnector.searchNodes(userProps, query);
             try {
                 List<GenericResource> genericResourceList = GenericResourceDeserializer.deserializeList(records);
-                responseObserver.onNext(ResourceFetchResponse.newBuilder().setResource(genericResourceList.get(0)).build());
+                ResourceFetchResponse.Builder builder = ResourceFetchResponse.newBuilder();
+                if (!genericResourceList.isEmpty()) {
+                    builder.setResource(genericResourceList.get(0));
+                }
+                responseObserver.onNext(builder.build());
                 responseObserver.onCompleted();
+
             } catch (Exception e) {
-                logger.error("Errored while fetching resource with id {}", request.getResourceId(), e);
-                responseObserver.onError(new Exception("Errored while fetching resource with id "
-                        + request.getResourceId() + ". Msg " + e.getMessage()));
+                logger.error("Errored while searching generic child resources; Message: {}", e.getMessage(), e);
+                String msg = "Errored while searching generic child resources " + e.getMessage();
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
             }
-        } else {
-            logger.error("Could not find a generic resource with id {}", request.getResourceId());
-            responseObserver.onError(new Exception("Could not find a generic resource with id "
-                    + request.getResourceId()));
+
+        } catch (Exception ex) {
+            logger.error("Error occurred while fetching child resource {}", request.getResourceId());
+            String msg = "Error occurred while creating resource with id" + request.getResourceId();
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
         }
     }
 
     @Override
     public void createResource(ResourceCreateRequest request, StreamObserver<ResourceCreateResponse> responseObserver) {
-        super.createResource(request, responseObserver);
+        try {
+            AuthenticatedUser callUser = request.getAuthToken().getAuthenticatedUser();
+
+            String type = request.getResource().getType();
+
+            Map<String, Object> userProps = new HashMap<>();
+            userProps.put("username", callUser.getUsername());
+            userProps.put("tenantId", callUser.getTenantId());
+
+
+            String storagePreferenceId = "";
+
+            if (request.getResource().getStoragePreferenceCase().name()
+                    .equals(AnyStoragePreference.StorageCase.S3STORAGEPREFERENCE)) {
+                storagePreferenceId = request.getResource().getS3Preference().getStoragePreferenceId();
+            } else if (request.getResource().getStoragePreferenceCase().name()
+                    .equals(AnyStoragePreference.StorageCase.SSHSTORAGEPREFERENCE)) {
+                storagePreferenceId = request.getResource().getSshPreference().getStoragePreferenceId();
+            }
+
+            String entityId = request.getResource().getResourceId();
+            Map<String, Object> serializedMap = GenericResourceSerializer.serializeToMap(request.getResource());
+            Optional<Entity> exEntity = CustosUtils.mergeResourceEntity(custosClientProvider, callUser.getTenantId(), storagePreferenceId, type, entityId,
+                    request.getResource().getResourceName(), request.getResource().getResourceName(),
+                    callUser.getUsername());
+
+            if (exEntity.isPresent()) {
+                serializedMap.put("description", exEntity.get().getDescription());
+                serializedMap.put("name", exEntity.get().getName());
+                serializedMap.put("createdTime", String.valueOf(exEntity.get().getCreatedAt()));
+                serializedMap.put("tenantId", callUser.getTenantId());
+                serializedMap.put("entityId", exEntity.get().getId());
+                serializedMap.put("entityType", exEntity.get().getType());
+
+                HashMap<String, Object> hashMap = new HashMap<>();
+
+                if (!storagePreferenceId.isEmpty()) {
+                    this.neo4JConnector.mergeNodesWithParentChildRelationShip(serializedMap, new HashMap<>(),
+                            request.getResource().getType(), StoragePreferenceConstants.STORAGE_PREFERENCE_LABEL,
+                            callUser.getUsername(), entityId, storagePreferenceId, callUser.getTenantId());
+                } else {
+                    this.neo4JConnector.mergeNode(hashMap, request.getResource().getType(),
+                            callUser.getUsername(), entityId, callUser.getTenantId());
+                }
+            } else {
+                logger.error("Error occurred while creating resource entity in Custos {}", request.getResource().getResourceId());
+                String msg = "Error occurred while creating resource entity in Custos with id"
+                        + request.getResource().getResourceId();
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+
+        } catch (Exception ex) {
+            logger.error("Error occurred while creating resource {}", request.getResource().getResourceId());
+            String msg = "Error occurred while creating resource" + ex.getMessage();
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+    }
+
+
+    @Override
+    public void fetchChildResources(ChildResourceFetchRequest request,
+                                    StreamObserver<ChildResourceFetchResponse> responseObserver) {
+        try {
+            AuthenticatedUser callUser = request.getAuthToken().getAuthenticatedUser();
+
+            String resourceId = request.getResourceId();
+            String type = request.getType();
+            int depth = request.getDepth();
+
+            Map<String, Object> userProps = new HashMap<>();
+            userProps.put("username", callUser.getUsername());
+            userProps.put("tenantId", callUser.getTenantId());
+            userProps.put("entityId", resourceId);
+
+            String query = " MATCH (u:User),  (r:" + type + ") where u.username = $username AND u.tenantId = $tenantId AND " +
+                    " r.entityId = $entityId AND r.tenantId = $tenantId" +
+                    " OPTIONAL MATCH (cg:Group)-[:CHILD_OF*]->(g:Group)<-[:MEMBER_OF]-(u)" +
+                    " OPTIONAL MATCH (u)<-[:SHARED_WITH]-(r)<-[:CHILD_OF*]-(cr)" +
+                    " OPTIONAL MATCH (g)<-[:SHARED_WITH]-(r)<-[:CHILD_OF*]-(chgr)" +
+                    " OPTIONAL MATCH (cg)<-[:SHARED_WITH]-(r)<-[:CHILD_OF*]-(chcgr)" +
+                    " return distinct  cr, chgr, chcgr";
+
+            if (depth == 1) {
+                query = " MATCH (u:User),  (r:" + type + ") where u.username = $username AND u.tenantId = $tenantId AND " +
+                        " r.entityId = $entityId AND r.tenantId = $tenantId" +
+                        " OPTIONAL MATCH (cg:Group)-[:CHILD_OF*]->(g:Group)<-[:MEMBER_OF]-(u)" +
+                        " OPTIONAL MATCH (u)<-[:SHARED_WITH]-(r)<-[:CHILD_OF]-(cr)" +
+                        " OPTIONAL MATCH (g)<-[:SHARED_WITH]-(r)<-[:CHILD_OF]-(chgr)" +
+                        " OPTIONAL MATCH (cg)<-[:SHARED_WITH]-(r)<-[:CHILD_OF]-(chcgr)" +
+                        " return distinct  cr, chgr, chcgr";
+            }
+
+            List<Record> records = this.neo4JConnector.searchNodes(userProps, query);
+
+            try {
+                List<GenericResource> genericResourceList = GenericResourceDeserializer.deserializeList(records);
+                ChildResourceFetchResponse.Builder builder = ChildResourceFetchResponse.newBuilder();
+                builder.addAllResources(genericResourceList);
+                responseObserver.onNext(builder.build());
+                responseObserver.onCompleted();
+
+            } catch (Exception e) {
+                logger.error("Errored while searching generic child resources; Message: {}", e.getMessage(), e);
+                String msg = "Errored while searching generic child resources" + e.getMessage();
+                responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+            }
+
+        } catch (Exception ex) {
+            logger.error("Error occurred while fetching child resource {}", request.getResourceId());
+            responseObserver.onError(Status.INTERNAL.withDescription("Error occurred while fetching child resource"
+                    + ex.getMessage()).asRuntimeException());
+        }
     }
 
     @Override
@@ -88,28 +224,203 @@ public class ResourceServiceHandler extends ResourceServiceGrpc.ResourceServiceI
 
     @Override
     public void searchResource(ResourceSearchRequest request, StreamObserver<ResourceSearchResponse> responseObserver) {
-        AuthenticatedUser callUser = request.getAuthToken().getAuthenticatedUser();
+        try {
+            AuthenticatedUser callUser = request.getAuthToken().getAuthenticatedUser();
 
-        // TODO review (u)-[r4:MEMBER_OF]->(g2:Group)<-[r5:SHARED_WITH]-(sp),
-//        List<Record> records = this.neo4JConnector.searchNodes(
-//                "MATCH (u:User)-[r1:MEMBER_OF]->(g:Group)<-[r2:SHARED_WITH]-(s:Storage)-[r3:HAS_PREFERENCE]->(sp:StoragePreference)-[r6:HAS_RESOURCE]->(res:Resource), " +
-//                        "(u)-[r7:MEMBER_OF]->(g3:Group)<-[r8:SHARED_WITH]-(res) " +
-//                        "where u.userId = '" + callUser.getUsername() + "' return distinct res, sp, s");
+            List<ResourceSearchQuery> resourceSearchQueries = request.getQueriesList();
+            ResourceSearchQuery searchQuery = resourceSearchQueries.get(0);
+            int depth = request.getDepth();
 
-        List<Record> records = this.neo4JConnector.searchNodes("match (u:User)-[:HAS_PERMISSION]->(r)  where u.username='" + callUser.getUsername() + "'optional match (u)-[:MEMBER_OF]->(g)-[:HAS_PERMISSION]->(m)<-[:CHILD_OF]-(p) " +
-                "return distinct r, m,p");
+            if (searchQuery.getField().equals("type")) {
+                String value = searchQuery.getValue();
 
+                Map<String, Object> userProps = new HashMap<>();
+                userProps.put("username", callUser.getUsername());
+                userProps.put("tenantId", callUser.getTenantId());
 
+                String query = " MATCH (u:User) where u.username = $username AND u.tenantId = $tenantId" +
+                        " OPTIONAL MATCH (g:Group)<-[:MEMBER_OF]-(u) " +
+                        " OPTIONAL MATCH (u)<-[:SHARED_WITH]-(m)<-[:CHILD_OF*]-(rm:" + value + ")" +
+                        " , (r:" + value + ")-[:SHARED_WITH]->(u)" +
+                        " OPTIONAL MATCH (g)<-[:SHARED_WITH]-(mg)<-[:CHILD_OF*]-(rmg:" + value + ")" +
+                        " , (rg:" + value + ")-[:SHARED_WITH]->(g)" +
+                        " return distinct  rm, r,rmg,rg ";
+
+                if (depth == 1) {
+                    query = " MATCH (u:User) where u.username = $username AND u.tenantId = $tenantId" +
+                            " OPTIONAL MATCH (g:Group)<-[:MEMBER_OF]-(u) " +
+                            " OPTIONAL MATCH (r:" + value + ")-[:SHARED_WITH]->(u)" +
+                            " OPTIONAL MATCH (rg:" + value + ")-[:SHARED_WITH]->(g)" +
+                            " return distinct   r, rg ";
+                }
+
+                List<Record> records = this.neo4JConnector.searchNodes(userProps, query);
+
+
+                List<GenericResource> genericResourceList = GenericResourceDeserializer.deserializeList(records);
+                ResourceSearchResponse.Builder builder = ResourceSearchResponse.newBuilder();
+                builder.addAllResources(genericResourceList);
+                responseObserver.onNext(builder.build());
+                responseObserver.onCompleted();
+            }
+
+        } catch (Exception e) {
+            logger.error("Errored while searching generic resources; Message: {}", e.getMessage(), e);
+            responseObserver.onError(Status.INTERNAL.withDescription("Errored while searching generic resources "
+                    + e.getMessage()).asRuntimeException());
+        }
+
+    }
+
+
+    @Override
+    public void addChildMembership(AddChildResourcesMembershipRequest request,
+                                   StreamObserver<OperationStatusResponse> responseObserver) {
+        try {
+            AuthenticatedUser callUser = request.getAuthToken().getAuthenticatedUser();
+            GenericResource resource = request.getParentResource();
+            List<GenericResource> childResources = request.getChildResourcesList();
+
+            List<GenericResource> allResources = new ArrayList<>();
+            allResources.add(resource);
+            allResources.addAll(childResources);
+
+            //TODO: can create raise conditions please move to DB level logic
+            allResources.forEach(res -> {
+                try {
+                    if (!hasAccessForResource(callUser.getUsername(), callUser.getTenantId(), res.getResourceId(), res.getType())) {
+                        String msg = " Don't have access to change memberships";
+                        responseObserver.onError(Status.PERMISSION_DENIED.withDescription(msg).asRuntimeException());
+                        return;
+                    }
+                } catch (Exception exception) {
+                    logger.error(" Error occurred while checking for permissions: Message {} "
+                            + exception.getMessage(), exception);
+                    String msg = " Error occurred while checking for permissions ";
+                    responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+                    return;
+                }
+            });
+
+
+            childResources.forEach(childResource -> {
+                Map<String, Object> userProps = new HashMap<>();
+                userProps.put("tenantId", callUser.getTenantId());
+                userProps.put("entityId", resource.getResourceId());
+                userProps.put("childEntityId", childResource.getResourceId());
+                String query = "MATCH  (r:" + resource.getType() + "), (cr:" + childResource.getType() + ")  where " +
+                        " r.entityId = $entityId AND r.tenantId = $tenantId  AND cr.entityId = $childEntityId AND cr.tenantId = $tenantId " +
+                        " MERGE (cr)-[:CHILD_OF]->(r) return r, cr";
+                this.neo4JConnector.runTransactionalQuery(userProps, query);
+            });
+
+            responseObserver.onNext(OperationStatusResponse.newBuilder().setStatus(true).build());
+            responseObserver.onCompleted();
+        } catch (Exception e) {
+            String msg = " Error occurred while adding  child memberships " + e.getMessage();
+            logger.error(" Error occurred while adding  child memberships: Messages {} ", e.getMessage(), e);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+    }
+
+    @Override
+    public void deleteChildMembership(DeleteChildResourcesMembershipRequest request,
+                                      StreamObserver<OperationStatusResponse> responseObserver) {
         try {
-            List<GenericResource> genericResourceList = GenericResourceDeserializer.deserializeList(records);
-            ResourceSearchResponse.Builder builder = ResourceSearchResponse.newBuilder();
-            builder.addAllResources(genericResourceList);
-            responseObserver.onNext(builder.build());
+
+            AuthenticatedUser callUser = request.getAuthToken().getAuthenticatedUser();
+            GenericResource resource = request.getParentResource();
+            List<GenericResource> childResources = request.getChildResourcesList();
+
+            List<GenericResource> allResources = new ArrayList<>();
+            allResources.add(resource);
+            allResources.addAll(childResources);
+
+            //TODO: can create raise conditions please move to DB level logic
+            allResources.forEach(res -> {
+                try {
+                    if (!hasAccessForResource(callUser.getUsername(), callUser.getTenantId(), res.getResourceId(), res.getType())) {
+                        String msg = " Don't have access to change memberships";
+                        responseObserver.onError(Status.PERMISSION_DENIED.withDescription(msg).asRuntimeException());
+                        return;
+                    }
+                } catch (Exception exception) {
+                    logger.error(" Error occurred while checking for permissions: Message {} "
+                            + exception.getMessage(), exception);
+                    String msg = " Error occurred while checking for permissions ";
+                    responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+                    return;
+                }
+            });
+
+
+            childResources.forEach(childResource -> {
+                Map<String, Object> userProps = new HashMap<>();
+                userProps.put("tenantId", callUser.getTenantId());
+                userProps.put("entityId", resource.getResourceId());
+                userProps.put("childEntityId", childResource.getResourceId());
+                String query = "MATCH  (r:" + resource.getType() + "), (cr:" + childResource.getType() + ")  where " +
+                        " r.entityId = $entityId AND r.tenantId = $tenantId  AND cr.entityId = $childEntityId AND cr.tenantId = $tenantId " +
+                        " MATCH (cr)-[crel:CHILD_OF]->(r) delete crel";
+                this.neo4JConnector.runTransactionalQuery(userProps, query);
+            });
+
+            responseObserver.onNext(OperationStatusResponse.newBuilder().setStatus(true).build());
             responseObserver.onCompleted();
 
+
         } catch (Exception e) {
-            logger.error("Errored while searching generic resources; Message: {}", e.getMessage(), e);
-            responseObserver.onError(e);
+            String msg = " Error occurred while deleting  child memberships " + e.getMessage();
+            logger.error(" Error occurred while fetching  parent resources: Messages {} ", e.getMessage(), e);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
+        }
+
+
+    }
+
+
+    @Override
+    public void fetchParentResources(ParentResourcesFetchRequest request, StreamObserver<ParentResourcesFetchResponse> responseObserver) {
+        try {
+            AuthenticatedUser callUser = request.getAuthToken().getAuthenticatedUser();
+            String resourseId = request.getResourceId();
+            String type = request.getType();
+            int depth = request.getDepth();
+            if (depth == 0) {
+                depth = 1;
+            }
+
+            if (hasAccessForResource(callUser.getUsername(), callUser.getTenantId(), resourseId, type)) {
+                Map<String, Object> userProps = new HashMap<>();
+                userProps.put("tenantId", callUser.getTenantId());
+                userProps.put("entityId", resourseId);
+                String query = "MATCH  (r:" + type + ")  where  r.entityId = $entityId AND r.tenantId = $tenantId" +
+                        " MATCH (r)-[ch:CHILD_OF*1.." + depth + "]->(m) return distinct m";
+                List<Record> records = this.neo4JConnector.searchNodes(userProps, query);
+                if (!records.isEmpty()) {
+                    List<GenericResource> genericResourceList = GenericResourceDeserializer.deserializeList(records);
+                    Map<String, GenericResource> genericResourceMap = new HashMap<>();
+                    AtomicInteger count = new AtomicInteger();
+                    genericResourceList.forEach(resource -> {
+                        genericResourceMap.put(String.valueOf(count.get()), resource);
+                        count.getAndIncrement();
+                    });
+
+                    ParentResourcesFetchResponse.Builder builder = ParentResourcesFetchResponse.newBuilder();
+                    builder.putAllProperties(genericResourceMap);
+                    responseObserver.onNext(builder.build());
+                    responseObserver.onCompleted();
+                }
+            } else {
+                String msg = " Don't have access to change memberships";
+                responseObserver.onError(Status.PERMISSION_DENIED.withDescription(msg).asRuntimeException());
+                return;
+            }
+        } catch (Exception ex) {
+            String msg = " Error occurred while fetching  parent resources " + ex.getMessage();
+            logger.error(" Error occurred while fetching  parent resources: Messages {} ", ex.getMessage(), ex);
+            responseObserver.onError(Status.INTERNAL.withDescription(msg).asRuntimeException());
         }
     }
 
@@ -143,4 +454,27 @@ public class ResourceServiceHandler extends ResourceServiceGrpc.ResourceServiceI
                     + request.getResourceId() + ". Msg " + e.getMessage()));
         }
     }
+
+
+    private boolean hasAccessForResource(String username, String tenantId, String resourceId, String type) throws Exception {
+        Map<String, Object> userProps = new HashMap<>();
+        userProps.put("username", username);
+        userProps.put("tenantId", tenantId);
+        userProps.put("entityId", resourceId);
+
+        String query = " MATCH (u:User),  (r:" + type + ") where u.username = $username AND u.tenantId = $tenantId AND " +
+                " r.entityId = $entityId AND r.tenantId = $tenantId" +
+                " OPTIONAL MATCH (cg:Group)-[:CHILD_OF*]->(g:Group)<-[:MEMBER_OF]-(u)" +
+                " return case when  exists((u)<-[:SHARED_WITH]-(r)) OR  exists((g)<-[:SHARED_WITH]-(r)) OR   " +
+                "exists((cg)<-[:SHARED_WITH]-(r)) then r  else NULL end as value";
+
+        List<Record> records = this.neo4JConnector.searchNodes(userProps, query);
+
+        List<GenericResource> genericResourceList = GenericResourceDeserializer.deserializeList(records);
+        if (genericResourceList.isEmpty()) {
+            return false;
+        }
+
+        return true;
+    }
 }
diff --git a/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/interceptors/Authenticator.java b/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/interceptors/Authenticator.java
index 03fe2e6..e793e41 100644
--- a/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/interceptors/Authenticator.java
+++ b/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/interceptors/Authenticator.java
@@ -28,7 +28,7 @@ public class Authenticator implements ServiceInterceptor {
     @Override
     public <ReqT> ReqT intercept(String method, Metadata headers, ReqT msg) throws IOException {
         IdentityManagementClient identityManagementClient = custosClientProvider.getIdentityManagementClient();
-        Optional<String> token = getAccessToken(msg);
+        Optional<String> token = getAccessToken(msg, headers);
         User user = identityManagementClient.getUser(token.get());
         AuthenticatedUser authenticatedUser = AuthenticatedUser.newBuilder()
                 .setUsername(user.getUsername())
@@ -42,18 +42,22 @@ public class Authenticator implements ServiceInterceptor {
     }
 
 
-    private Optional<String> getAccessToken(Object msg) {
-        Descriptors.FieldDescriptor fieldDescriptor =
-                ((com.google.protobuf.GeneratedMessageV3) msg).getDescriptorForType().findFieldByName("authToken");
-        Object value = ((com.google.protobuf.GeneratedMessageV3) msg).getField(fieldDescriptor);
-        DRMSServiceAuthToken drmsServiceAuthToken = (DRMSServiceAuthToken) value;
-        return Optional.ofNullable(drmsServiceAuthToken.getAccessToken());
+    private Optional<String> getAccessToken(Object msg, Metadata headers) {
+        Optional<String> tokenHeaders = getTokenFromHeader(headers);
+        if (tokenHeaders.isEmpty()) {
+            Descriptors.FieldDescriptor fieldDescriptor =
+                    ((com.google.protobuf.GeneratedMessageV3) msg).getDescriptorForType().findFieldByName("auth_token");
+            Object value = ((com.google.protobuf.GeneratedMessageV3) msg).getField(fieldDescriptor);
+            DRMSServiceAuthToken drmsServiceAuthToken = (DRMSServiceAuthToken) value;
+            return Optional.ofNullable(drmsServiceAuthToken.getAccessToken());
+        }
+        return Optional.ofNullable(tokenHeaders.get());
     }
 
     private Object setAuthenticatedUser(Object msg, AuthenticatedUser user) {
 
         Descriptors.FieldDescriptor fieldDescriptor =
-                ((com.google.protobuf.GeneratedMessageV3) msg).getDescriptorForType().findFieldByName("authToken");
+                ((com.google.protobuf.GeneratedMessageV3) msg).getDescriptorForType().findFieldByName("auth_token");
         Object value = ((com.google.protobuf.GeneratedMessageV3) msg).getField(fieldDescriptor);
         DRMSServiceAuthToken drmsServiceAuthToken = (DRMSServiceAuthToken) value;
         drmsServiceAuthToken = drmsServiceAuthToken.toBuilder().setAuthenticatedUser(user).build();
@@ -61,4 +65,18 @@ public class Authenticator implements ServiceInterceptor {
 
         return builder.setField(fieldDescriptor, drmsServiceAuthToken).build();
     }
+
+    public Optional<String> getTokenFromHeader(Metadata headers) {
+        String tokenWithBearer = headers.get(Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER));
+        if (tokenWithBearer == null) {
+            tokenWithBearer = headers.get(Metadata.Key.of("Authorization", Metadata.ASCII_STRING_MARSHALLER));
+        }
+        if (tokenWithBearer == null) {
+            return Optional.empty();
+        }
+        String prefix = "Bearer";
+        String token = tokenWithBearer.substring(prefix.length());
+        return Optional.ofNullable(token.trim());
+    }
+
 }
diff --git a/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/utils/CustosUtils.java b/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/utils/CustosUtils.java
index d82d39e..78256df 100644
--- a/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/utils/CustosUtils.java
+++ b/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/utils/CustosUtils.java
@@ -9,6 +9,7 @@ import org.apache.custos.sharing.service.EntityType;
 import org.apache.custos.sharing.service.Status;
 
 import java.io.IOException;
+import java.util.Optional;
 
 public class CustosUtils {
 
@@ -75,4 +76,38 @@ public class CustosUtils {
         }
     }
 
+
+    public static Optional<Entity> mergeResourceEntity(CustosClientProvider custosClientProvider, String tenantId, String storagePreferenceId,
+                                                       String entityTypeId, String entityId, String entityName, String description, String username) throws IOException {
+        SharingManagementClient sharingManagementClient = custosClientProvider.getSharingManagementClient();
+        EntityType entityType = EntityType.newBuilder().setId(entityTypeId).build();
+        EntityType type = sharingManagementClient.getEntityType(tenantId, entityType);
+        if (!type.isInitialized() || type.getId().isEmpty()) {
+            EntityType storEntityType = EntityType.newBuilder()
+                    .setId(entityTypeId)
+                    .setName(entityTypeId)
+                    .setDescription("Resource  entity type " + entityTypeId)
+                    .build();
+            sharingManagementClient.createEntityType(tenantId, storEntityType);
+        }
+        Entity entity = Entity.newBuilder()
+                .setId(entityId)
+                .setName(entityName)
+                .setOwnerId(username)
+                .setParentId(storagePreferenceId)
+                .setType(entityTypeId)
+                .setDescription(description)
+                .build();
+
+        Status status = sharingManagementClient.isEntityExists(tenantId, entity);
+        if (!status.getStatus()) {
+            sharingManagementClient.createEntity(tenantId, entity);
+            return Optional.ofNullable(sharingManagementClient.getEntity(tenantId, entity));
+        }
+
+        return Optional.empty();
+
+    }
+
+
 }
diff --git a/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/utils/Utils.java b/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/utils/Utils.java
index 215045a..b373ce4 100644
--- a/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/utils/Utils.java
+++ b/data-resource-management-service/drms-api/src/main/java/org/apache/airavata/drms/api/utils/Utils.java
@@ -21,4 +21,5 @@ public class Utils {
 
 
 
+
 }
diff --git a/data-resource-management-service/drms-core/src/main/java/org/apache/airavata/drms/core/Neo4JConnector.java b/data-resource-management-service/drms-core/src/main/java/org/apache/airavata/drms/core/Neo4JConnector.java
index c7b9d89..a1dada0 100644
--- a/data-resource-management-service/drms-core/src/main/java/org/apache/airavata/drms/core/Neo4JConnector.java
+++ b/data-resource-management-service/drms-core/src/main/java/org/apache/airavata/drms/core/Neo4JConnector.java
@@ -85,7 +85,7 @@ public class Neo4JConnector {
         parameters.put("tenantId", tenantId);
         Transaction tx = session.beginTransaction();
         tx.run("MATCH (u:User)  where u.username = $username AND  u.tenantId = $tenantId " +
-                " MERGE (n:" + label + " {entityId: $entityId,tenantId: $tenantId}) ON MATCH  SET n += $props ON CREATE SET n = +$props" +
+                " MERGE (n:" + label + " {entityId: $entityId,tenantId: $tenantId}) ON MATCH  SET n += $props ON CREATE SET n += $props" +
                 " MERGE (n)-[r2:SHARED_WITH {permission:'OWNER'}]->(u) return n", parameters);
         tx.commit();
         tx.close();
diff --git a/data-resource-management-service/drms-core/src/main/java/org/apache/airavata/drms/core/deserializer/GenericResourceDeserializer.java b/data-resource-management-service/drms-core/src/main/java/org/apache/airavata/drms/core/deserializer/GenericResourceDeserializer.java
index b5458cb..f4a45c5 100644
--- a/data-resource-management-service/drms-core/src/main/java/org/apache/airavata/drms/core/deserializer/GenericResourceDeserializer.java
+++ b/data-resource-management-service/drms-core/src/main/java/org/apache/airavata/drms/core/deserializer/GenericResourceDeserializer.java
@@ -82,6 +82,9 @@ public class GenericResourceDeserializer {
             }
             for (String field : node.asMap().keySet()) {
                 genericResourceBuilder.putProperties(field, String.valueOf(node.asMap().get(field)));
+                if (field.equals("entityId")){
+                    genericResourceBuilder.setResourceId(String.valueOf(node.asMap().get(field)));
+                }
             }
             return genericResourceBuilder.build();
         }).collect(Collectors.toList());
diff --git a/data-resource-management-service/drms-core/src/main/java/org/apache/airavata/drms/core/serializer/GenericResourceSerializer.java b/data-resource-management-service/drms-core/src/main/java/org/apache/airavata/drms/core/serializer/GenericResourceSerializer.java
new file mode 100644
index 0000000..dc201c8
--- /dev/null
+++ b/data-resource-management-service/drms-core/src/main/java/org/apache/airavata/drms/core/serializer/GenericResourceSerializer.java
@@ -0,0 +1,28 @@
+package org.apache.airavata.drms.core.serializer;
+
+import com.google.protobuf.Descriptors;
+import org.apache.airavata.datalake.drms.resource.GenericResource;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class GenericResourceSerializer {
+
+
+    public static Map<String, Object> serializeToMap(GenericResource anyResource) {
+
+        Map<String, Object> fields = new HashMap<>();
+        Map<Descriptors.FieldDescriptor, Object> allFields = null;
+
+        if (allFields != null) {
+            allFields.forEach((descriptor, value) -> {
+                String fieldName = descriptor.getJsonName();
+                fields.put(fieldName, value);
+            });
+        }
+
+        return fields;
+    }
+
+
+}
diff --git a/data-resource-management-service/drms-custos-synchronizer/src/main/java/org/apache/airavata/drms/custos/synchronizer/CustosSynchronizer.java b/data-resource-management-service/drms-custos-synchronizer/src/main/java/org/apache/airavata/drms/custos/synchronizer/CustosSynchronizer.java
index 32bba38..2631ba7 100644
--- a/data-resource-management-service/drms-custos-synchronizer/src/main/java/org/apache/airavata/drms/custos/synchronizer/CustosSynchronizer.java
+++ b/data-resource-management-service/drms-custos-synchronizer/src/main/java/org/apache/airavata/drms/custos/synchronizer/CustosSynchronizer.java
@@ -29,9 +29,10 @@ public class CustosSynchronizer implements CommandLineRunner {
         LOGGER.info("Starting Custos synchronizer ...");
         if (args.length > 0) {
             configFilePath = args[0];
+        } else {
+            configFilePath = "/Users/isururanawaka/Documents/Airavata_Repository/airavata-data-lake" +
+                    "/data-resource-management-service/drms-custos-synchronizer/src/main/resources/config.yml";
         }
-        configFilePath = "/Users/isururanawaka/Documents/Airavata_Repository/airavata-data-lake" +
-                "/data-resource-management-service/drms-custos-synchronizer/src/main/resources/config.yml";
 
         LOGGER.info("Configuring scheduler ...");
         Utils.initializeConnectors(Utils.loadConfiguration(configFilePath));
diff --git a/data-resource-management-service/drms-rest-proxy/src/main/resources/drms.pb b/data-resource-management-service/drms-rest-proxy/src/main/resources/drms.pb
index c36c421..e195bc9 100644
Binary files a/data-resource-management-service/drms-rest-proxy/src/main/resources/drms.pb and b/data-resource-management-service/drms-rest-proxy/src/main/resources/drms.pb differ
diff --git a/data-resource-management-service/drms-rest-proxy/src/main/resources/envoy.yaml b/data-resource-management-service/drms-rest-proxy/src/main/resources/envoy.yaml
index 3340da0..317bd64 100644
--- a/data-resource-management-service/drms-rest-proxy/src/main/resources/envoy.yaml
+++ b/data-resource-management-service/drms-rest-proxy/src/main/resources/envoy.yaml
@@ -45,4 +45,4 @@ static_resources:
       hosts:
         - socket_address:
             address: host.docker.internal
-            port_value: 6565
\ No newline at end of file
+            port_value: 7070
\ No newline at end of file
diff --git a/data-resource-management-service/drms-rest-proxy/src/main/resources/generator.txt b/data-resource-management-service/drms-rest-proxy/src/main/resources/generator.txt
new file mode 100644
index 0000000..cfa0643
--- /dev/null
+++ b/data-resource-management-service/drms-rest-proxy/src/main/resources/generator.txt
@@ -0,0 +1 @@
+protoc -I/Users/isururanawaka/Documents/GOOGLE_APIS/googleapis  -I/Users/isururanawaka/Documents/Airavata_Repository/airavata-data-lake/data-resource-management-service/drms-stubs/src/main/proto   --include_imports --include_source_info     --descriptor_set_out=drms.pb /Users/isururanawaka/Documents/Airavata_Repository/airavata-data-lake/data-resource-management-service/drms-stubs/src/main/proto/group/GroupService.proto /Users/isururanawaka/Documents/Airavata_Repository/airavata-data-lak [...]
\ No newline at end of file
diff --git a/data-resource-management-service/drms-stubs/drms.pb b/data-resource-management-service/drms-stubs/drms.pb
deleted file mode 100644
index c36c421..0000000
Binary files a/data-resource-management-service/drms-stubs/drms.pb and /dev/null differ
diff --git a/data-resource-management-service/drms-stubs/src/main/proto/resource/DRMSResource.proto b/data-resource-management-service/drms-stubs/src/main/proto/resource/DRMSResource.proto
index fb95271..23cc8cf 100644
--- a/data-resource-management-service/drms-stubs/src/main/proto/resource/DRMSResource.proto
+++ b/data-resource-management-service/drms-stubs/src/main/proto/resource/DRMSResource.proto
@@ -33,4 +33,6 @@ message GenericResource {
   }
   map<string, string> properties = 5;
   string type=6;
+  string parentResourcePath = 7;
+  string resourceName = 8;
 }
\ No newline at end of file
diff --git a/data-resource-management-service/drms-stubs/src/main/proto/resource/DRMSResourceService.proto b/data-resource-management-service/drms-stubs/src/main/proto/resource/DRMSResourceService.proto
index fa3a24a..f73804e 100644
--- a/data-resource-management-service/drms-stubs/src/main/proto/resource/DRMSResourceService.proto
+++ b/data-resource-management-service/drms-stubs/src/main/proto/resource/DRMSResourceService.proto
@@ -27,8 +27,21 @@ import "google/protobuf/empty.proto";
 
 
 message ResourceFetchRequest {
-  org.apache.airavata.datalake.drms.DRMSServiceAuthToken authToken = 1;
-  string resourceId = 2;
+  org.apache.airavata.datalake.drms.DRMSServiceAuthToken auth_token = 1;
+  string resource_id = 2;
+  string type = 3;
+}
+
+
+message ChildResourceFetchRequest {
+  org.apache.airavata.datalake.drms.DRMSServiceAuthToken auth_token = 1;
+  string resource_id = 2;
+  string type = 3;
+  int32 depth = 4;
+}
+
+message ChildResourceFetchResponse {
+  repeated org.apache.airavata.datalake.drms.resource.GenericResource resources = 1;
 }
 
 message ResourceFetchResponse {
@@ -36,7 +49,7 @@ message ResourceFetchResponse {
 }
 
 message ResourceCreateRequest {
-  org.apache.airavata.datalake.drms.DRMSServiceAuthToken authToken = 1;
+  org.apache.airavata.datalake.drms.DRMSServiceAuthToken auth_token = 1;
   org.apache.airavata.datalake.drms.resource.GenericResource resource = 2;
 }
 
@@ -45,7 +58,7 @@ message ResourceCreateResponse {
 }
 
 message ResourceUpdateRequest {
-  org.apache.airavata.datalake.drms.DRMSServiceAuthToken authToken = 1;
+  org.apache.airavata.datalake.drms.DRMSServiceAuthToken auth_token = 1;
   string resourceId = 2;
   org.apache.airavata.datalake.drms.resource.GenericResource resource = 3;
 }
@@ -55,7 +68,7 @@ message ResourceUpdateResponse {
 }
 
 message ResourceDeleteRequest {
-  org.apache.airavata.datalake.drms.DRMSServiceAuthToken authToken = 1;
+  org.apache.airavata.datalake.drms.DRMSServiceAuthToken auth_token = 1;
   string resourceId = 2;
 }
 
@@ -66,12 +79,13 @@ message ResourceSearchQuery {
 }
 
 message ResourceSearchRequest {
-  org.apache.airavata.datalake.drms.DRMSServiceAuthToken authToken = 1;
+  org.apache.airavata.datalake.drms.DRMSServiceAuthToken auth_token = 1;
   repeated ResourceSearchQuery queries = 2;
+  int32 depth = 4;
 }
 
 message ResourceSearchResponse {
-  org.apache.airavata.datalake.drms.DRMSServiceAuthToken authToken = 1;
+  org.apache.airavata.datalake.drms.DRMSServiceAuthToken auth_token = 1;
   repeated org.apache.airavata.datalake.drms.resource.GenericResource resources = 2;
 }
 
@@ -81,13 +95,13 @@ message Metadata {
 }
 
 message AddResourceMetadataRequest {
-  org.apache.airavata.datalake.drms.DRMSServiceAuthToken authToken = 1;
+  org.apache.airavata.datalake.drms.DRMSServiceAuthToken auth_token = 1;
   string resourceId = 2;
   Metadata metadata = 3;
 }
 
 message FetchResourceMetadataRequest {
-  org.apache.airavata.datalake.drms.DRMSServiceAuthToken authToken = 1;
+  org.apache.airavata.datalake.drms.DRMSServiceAuthToken auth_token = 1;
   string resourceId = 2;
 }
 
@@ -100,6 +114,37 @@ message FetchResourceMetadataResponse {
 }
 
 
+message AddChildResourcesMembershipRequest{
+  org.apache.airavata.datalake.drms.DRMSServiceAuthToken auth_token = 1;
+  org.apache.airavata.datalake.drms.resource.GenericResource parent_resource = 2;
+  repeated org.apache.airavata.datalake.drms.resource.GenericResource child_resources = 3;
+
+}
+
+message DeleteChildResourcesMembershipRequest{
+  org.apache.airavata.datalake.drms.DRMSServiceAuthToken auth_token = 1;
+  org.apache.airavata.datalake.drms.resource.GenericResource parent_resource = 2;
+  repeated org.apache.airavata.datalake.drms.resource.GenericResource child_resources = 3;
+}
+
+
+message ParentResourcesFetchRequest{
+  org.apache.airavata.datalake.drms.DRMSServiceAuthToken auth_token = 1;
+  string resource_id = 2;
+  string type =3;
+  int32 depth =4;
+
+}
+
+message ParentResourcesFetchResponse {
+    map<string, org.apache.airavata.datalake.drms.resource.GenericResource> properties = 1;
+}
+
+message OperationStatusResponse{
+  bool status = 1;
+}
+
+
 service ResourceService {
 
   rpc fetchResource (ResourceFetchRequest) returns (ResourceFetchResponse) {
@@ -128,7 +173,32 @@ service ResourceService {
 
   rpc searchResource (ResourceSearchRequest) returns (ResourceSearchResponse) {
     option (google.api.http) = {
-      post: "/v1.0/api/drms/resource/searchPreference"
+      post: "/v1.0/api/drms/resource/searchResource"
+    };
+  }
+
+  rpc fetchChildResources (ChildResourceFetchRequest) returns (ChildResourceFetchResponse) {
+    option (google.api.http) = {
+      get: "/v1.0/api/drms/resource/child"
+    };
+  }
+
+
+  rpc fetchParentResources (ParentResourcesFetchRequest) returns (ParentResourcesFetchResponse) {
+      option (google.api.http) = {
+      get: "/v1.0/api/drms/resource/parent"
+    };
+  }
+
+  rpc addChildMembership (AddChildResourcesMembershipRequest) returns (OperationStatusResponse) {
+    option (google.api.http) = {
+      post: "/v1.0/api/drms/resource/child"
+    };
+  }
+
+  rpc deleteChildMembership (DeleteChildResourcesMembershipRequest) returns (OperationStatusResponse) {
+    option (google.api.http) = {
+      delete: "/v1.0/api/drms/resource/child"
     };
   }