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

[airavata] branch storage-resource-profile created (now 687002b)

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

dimuthuupe pushed a change to branch storage-resource-profile
in repository https://gitbox.apache.org/repos/asf/airavata.git.


      at 687002b  Initial user stprage group preferences

This branch includes the following new commits:

     new 687002b  Initial user stprage group preferences

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[airavata] 01/01: Initial user stprage group preferences

Posted by di...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dimuthuupe pushed a commit to branch storage-resource-profile
in repository https://gitbox.apache.org/repos/asf/airavata.git

commit 687002b51be2f8a9fe5861cc8f13a5ba72d05825
Author: Dimuthu Wannipurage <di...@gmail.com>
AuthorDate: Fri Feb 12 01:21:08 2021 -0500

    Initial user stprage group preferences
---
 modules/resource-profile/pom.xml                   |  56 +++
 .../resource-profile-service/pom.xml               |  86 ++++
 .../profile/handler/storage/S3StorageHandler.java  | 450 +++++++++++++++++++++
 .../profile/handler/storage/SCPStorageHandler.java | 449 ++++++++++++++++++++
 .../resource/profile/service/AppConfig.java        |  30 ++
 .../service/ResourceProfileServiceApplication.java |  33 ++
 .../resource/profile/service/SampleClient.java     |  25 ++
 .../resource/profile/service/XmlConfiguration.java |  26 ++
 .../resource/profile/sharing/SharingImpl.java      |  36 ++
 .../s3/entity/S3StoGroupPreferenceEntity.java      |  89 ++++
 .../storage/s3/entity/S3StoGroupPreferenceId.java  |  62 +++
 .../s3/entity/S3StoGroupResourceProfileEntity.java | 112 +++++
 .../profile/storage/s3/entity/S3StorageEntity.java |  66 +++
 .../repository/S3StoGroupPreferenceRepository.java |  24 ++
 .../S3StoGroupResourceProfileRepository.java       |  23 ++
 .../storage/s3/repository/S3StorageRepository.java |  23 ++
 .../scp/entity/SCPStoGroupPreferenceEntity.java    | 104 +++++
 .../scp/entity/SCPStoGroupPreferenceId.java        |  63 +++
 .../entity/SCPStoGroupResourceProfileEntity.java   | 112 +++++
 .../storage/scp/entity/SCPStorageEntity.java       |  65 +++
 .../SCPStoGroupPreferenceRepository.java           |  24 ++
 .../SCPStoGroupResourceProfileRepository.java      |  23 ++
 .../scp/repository/SCPStorageRepository.java       |  24 ++
 .../src/main/resources/application.properties      |   2 +
 .../src/main/resources/applicationContext.xml      |  10 +
 .../resource-profile-stubs/pom.xml                 |  92 +++++
 .../src/main/proto/common.proto                    |   8 +
 .../src/main/proto/storage/s3/service.proto        | 158 ++++++++
 .../src/main/proto/storage/s3/stubs.proto          |  26 ++
 .../src/main/proto/storage/scp/service.proto       | 158 ++++++++
 .../src/main/proto/storage/scp/stubs.proto         |  27 ++
 pom.xml                                            |   9 +-
 32 files changed, 2488 insertions(+), 7 deletions(-)

diff --git a/modules/resource-profile/pom.xml b/modules/resource-profile/pom.xml
new file mode 100644
index 0000000..94d145b
--- /dev/null
+++ b/modules/resource-profile/pom.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>airavata</artifactId>
+        <groupId>org.apache.airavata</groupId>
+        <version>0.21-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>resource-profile</artifactId>
+    <packaging>pom</packaging>
+    <modules>
+        <module>resource-profile-stubs</module>
+        <module>resource-profile-service</module>
+    </modules>
+
+    <properties>
+        <maven.compiler.source>11</maven.compiler.source>
+        <maven.compiler.target>11</maven.compiler.target>
+        <protobuf.maven.plugin>0.5.1</protobuf.maven.plugin>
+        <os.maven.plugin>1.5.0.Final</os.maven.plugin>
+        <javax.annotation>1.3.2</javax.annotation>
+        <h2>1.4.191</h2>
+        <protobuf.java>3.10.0</protobuf.java>
+        <grpc.spring.boot>4.4.3</grpc.spring.boot>
+        <spring.boot.data.jpa>2.4.2</spring.boot.data.jpa>
+        <log4j.over.slf4j>1.7.26</log4j.over.slf4j>
+        <dozer>5.5.1</dozer>
+        <mariadb.jdbc>2.5.1</mariadb.jdbc>
+    </properties>
+
+</project>
\ No newline at end of file
diff --git a/modules/resource-profile/resource-profile-service/pom.xml b/modules/resource-profile/resource-profile-service/pom.xml
new file mode 100644
index 0000000..03fe6fc
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/pom.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>resource-profile</artifactId>
+        <groupId>org.apache.airavata</groupId>
+        <version>0.21-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>resource-profile-service</artifactId>
+
+    <properties>
+        <maven.compiler.source>11</maven.compiler.source>
+        <maven.compiler.target>11</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>io.github.lognet</groupId>
+            <artifactId>grpc-spring-boot-starter</artifactId>
+            <version>${grpc.spring.boot}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+            <version>${spring.boot.data.jpa}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.8.5</version>
+        </dependency>
+        <dependency>
+            <groupId>net.sf.dozer</groupId>
+            <artifactId>dozer</artifactId>
+            <version>${dozer}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <version>${h2}</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.airavata</groupId>
+            <artifactId>resource-profile-stubs</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jetbrains</groupId>
+            <artifactId>annotations</artifactId>
+            <version>RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/handler/storage/S3StorageHandler.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/handler/storage/S3StorageHandler.java
new file mode 100644
index 0000000..bad3e4d
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/handler/storage/S3StorageHandler.java
@@ -0,0 +1,450 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.airavata.resource.profile.handler.storage;
+
+import com.google.protobuf.Empty;
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import org.apache.airavata.resource.profile.service.s3.*;
+import org.apache.airavata.resource.profile.sharing.SharingImpl;
+import org.apache.airavata.resource.profile.sharing.SharingImpl.AccessLevel;
+import org.apache.airavata.resource.profile.storage.s3.entity.S3StoGroupPreferenceEntity;
+import org.apache.airavata.resource.profile.storage.s3.entity.S3StoGroupPreferenceId;
+import org.apache.airavata.resource.profile.storage.s3.entity.S3StoGroupResourceProfileEntity;
+import org.apache.airavata.resource.profile.storage.s3.entity.S3StorageEntity;
+import org.apache.airavata.resource.profile.storage.s3.repository.S3StoGroupPreferenceRepository;
+import org.apache.airavata.resource.profile.storage.s3.repository.S3StoGroupResourceProfileRepository;
+import org.apache.airavata.resource.profile.storage.s3.repository.S3StorageRepository;
+import org.apache.airavata.resource.profile.stubs.s3.S3Storage;
+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.Optional;
+
+@GRpcService
+public class S3StorageHandler extends S3StorageServiceGrpc.S3StorageServiceImplBase {
+
+    private static final Logger logger = LoggerFactory.getLogger(S3StorageHandler.class);
+
+    @Autowired
+    private S3StorageRepository storageRepository;
+
+    @Autowired
+    private S3StoGroupPreferenceRepository groupPreferenceRepository;
+
+    @Autowired
+    private S3StoGroupResourceProfileRepository groupResourceProfileRepository;
+
+    @Autowired
+    private SharingImpl sharingImpl;
+
+    private DozerBeanMapper mapper = new DozerBeanMapper();
+
+    @Override
+    public void createS3Storage(S3StorageCreateRequest request, StreamObserver<S3StorageCreateResponse> responseObserver) {
+
+        try {
+            S3StorageEntity savedEntity = storageRepository.save(mapper.map(request.getS3Storage(), S3StorageEntity.class));
+
+            sharingImpl.createSharingEntity("S3", savedEntity.getS3StorageId(), request.getAuthzToken(), AccessLevel.WRITE);
+
+            S3Storage savedStorage = mapper.map(savedEntity, S3Storage.newBuilder().getClass()).build();
+            responseObserver.onNext(S3StorageCreateResponse.newBuilder().setS3Storage(savedStorage).build());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to create the S3 Storage with bucket name {}", request.getS3Storage().getBucketName(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to create the S3 Storage with bucket name " + request.getS3Storage().getBucketName())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void updateS3Storage(S3StorageUpdateRequest request, StreamObserver<Empty> responseObserver) {
+
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("S3",
+                    request.getS3Storage().getS3StorageId(), request.getAuthzToken(), AccessLevel.WRITE);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for storage " + request.getS3Storage().getS3StorageId())
+                        .asRuntimeException());
+            }
+
+            boolean exists = storageRepository.existsById(request.getS3Storage().getS3StorageId());
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("S3 storage with id" + request.getS3Storage().getS3StorageId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            storageRepository.save(mapper.map(request.getS3Storage(), S3StorageEntity.class));
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to update the S3 Storage with id {}", request.getS3Storage().getS3StorageId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to update the S3 Storage with id " + request.getS3Storage().getS3StorageId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void removeS3Storage(S3StorageRemoveRequest request, StreamObserver<Empty> responseObserver) {
+
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("S3",
+                    request.getS3StorageId(), request.getAuthzToken(), AccessLevel.WRITE);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for storage " + request.getS3StorageId())
+                        .asRuntimeException());
+            }
+
+            boolean exists = storageRepository.existsById(request.getS3StorageId());
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("S3 storage with id " + request.getS3StorageId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            storageRepository.deleteById(request.getS3StorageId());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to remove the S3 Storage with id {}", request.getS3StorageId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to remove the S3 Storage with id " + request.getS3StorageId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void fetchS3Storage(S3StorageFetchRequest request, StreamObserver<S3StorageFetchResponse> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("S3",
+                    request.getS3StorageId(), request.getAuthzToken(), AccessLevel.READ);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for storage " + request.getS3StorageId())
+                        .asRuntimeException());
+            }
+
+            boolean exists = storageRepository.existsById(request.getS3StorageId());
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("S3 storage with id " + request.getS3StorageId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            Optional<S3StorageEntity> storageEntityOp = storageRepository.findById(request.getS3StorageId());
+
+            S3Storage fetchedStorage = mapper.map(storageEntityOp.get(), S3Storage.newBuilder().getClass()).build();
+            responseObserver.onNext(S3StorageFetchResponse.newBuilder().setS3Storage(fetchedStorage).build());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to fetch the S3 Storage with id {}", request.getS3StorageId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to fetch the S3 Storage with id " + request.getS3StorageId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void listS3Storage(S3StorageListRequest request, StreamObserver<S3StorageListResponse> responseObserver) {
+        responseObserver.onError(Status.INTERNAL
+                .withDescription("Method not implemented")
+                .asRuntimeException());
+    }
+
+    @Override
+    public void createS3StoGroupPreference(S3StoGroupPreferenceCreateRequest request, StreamObserver<S3StoGroupPreferenceCreateResponse> responseObserver) {
+
+        try {
+            S3StoGroupPreferenceEntity savedEntity = groupPreferenceRepository.save(mapper.map(request.getS3StoGroupPreference(), S3StoGroupPreferenceEntity.class));
+
+            sharingImpl.createSharingEntity("S3",
+                    savedEntity.getS3StorageId() + "-" + savedEntity.getS3GroupResourceProfileId(),
+                    request.getAuthzToken(), AccessLevel.WRITE);
+
+            responseObserver.onNext(mapper.map(savedEntity, S3StoGroupPreferenceCreateResponse.newBuilder().getClass()).build());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to create the S3 storage group preference with storage id {}",
+                    request.getS3StoGroupPreference().getS3StorageId(), e);
+
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to create the S3 storage group preference with storage id " +
+                            request.getS3StoGroupPreference().getS3StorageId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void updateS3StoGroupPreference(S3StoGroupPreferenceUpdateRequest request, StreamObserver<Empty> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("S3",
+                    request.getS3StoGroupPreference().getS3StorageId() + "-" + request.getS3StoGroupPreference().getS3GroupResourceProfileId(),
+                    request.getAuthzToken(), AccessLevel.WRITE);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for storage group preference with storage id " +
+                                request.getS3StoGroupPreference().getS3StorageId())
+                        .asRuntimeException());
+            }
+
+            boolean exists = groupPreferenceRepository.existsById(new S3StoGroupPreferenceId(
+                    request.getS3StoGroupPreference().getS3StorageId(),
+                    request.getS3StoGroupPreference().getS3GroupResourceProfileId()));
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("S3 storage with id" + request.getS3StoGroupPreference().getS3StorageId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            groupPreferenceRepository.save(mapper.map(request.getS3StoGroupPreference(), S3StoGroupPreferenceEntity.class));
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to update the S3 Storage with id {}", request.getS3StoGroupPreference().getS3StorageId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to update the S3 Storage with id " + request.getS3StoGroupPreference().getS3StorageId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void removeS3StoGroupPreference(S3StoGroupPreferenceRemoveRequest request, StreamObserver<Empty> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("S3",
+                    request.getS3StorageId() + "-" + request.getS3GroupResourceProfileId(),
+                    request.getAuthzToken(), AccessLevel.WRITE);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for storage group preference with storage id  " +
+                                request.getS3StorageId())
+                        .asRuntimeException());
+            }
+
+            S3StoGroupPreferenceId id = new S3StoGroupPreferenceId(
+                    request.getS3StorageId(),
+                    request.getS3GroupResourceProfileId());
+
+            boolean exists = groupPreferenceRepository.existsById(id);
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("S3 storage group preference with storage id " + request.getS3StorageId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            groupPreferenceRepository.deleteById(id);
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to remove the S3 storage group preference with storage id {}", request.getS3StorageId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to remove the S3 storage group preference with storage id " + request.getS3StorageId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void fetchS3StoGroupPreference(S3StoGroupPreferenceFetchRequest request, StreamObserver<S3StoGroupPreferenceFetchResponse> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("S3",
+                    request.getS3StorageId() + "-" + request.getS3GroupResourceProfileId(),
+                    request.getAuthzToken(), AccessLevel.WRITE);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for storage group preference with storage id  " +
+                                request.getS3StorageId())
+                        .asRuntimeException());
+            }
+
+            S3StoGroupPreferenceId id = new S3StoGroupPreferenceId(
+                    request.getS3StorageId(),
+                    request.getS3GroupResourceProfileId());
+
+            boolean exists = groupPreferenceRepository.existsById(id);
+
+            Optional<S3StoGroupPreferenceEntity> groupPreferenceOp = groupPreferenceRepository.findById(id);
+
+            responseObserver.onNext(mapper.map(groupPreferenceOp.get(),
+                    S3StoGroupPreferenceFetchResponse.newBuilder().getClass()).build());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to fetch the S3 storage group preference with storage id {}", request.getS3StorageId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to fetch the S3 storage group preference with storage id  " + request.getS3StorageId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void createS3StoGroupResourceProfile(S3StoGroupResourceProfileCreateRequest request, StreamObserver<S3StoGroupResourceProfileCreateResponse> responseObserver) {
+        try {
+            S3StoGroupResourceProfileEntity savedEntity = groupResourceProfileRepository.save(
+                    mapper.map(request.getS3StoGroupResourceProfile(), S3StoGroupResourceProfileEntity.class));
+
+            sharingImpl.createSharingEntity("S3", savedEntity.getS3GroupResourceProfileId(),
+                    request.getAuthzToken(), AccessLevel.WRITE);
+
+            responseObserver.onNext(mapper.map(savedEntity,
+                    S3StoGroupResourceProfileCreateResponse.newBuilder().getClass()).build());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to create the S3 group resource profile with name {}",
+                    request.getS3StoGroupResourceProfile().getS3GroupResourceProfileName(), e);
+
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to create the S3 group resource profile with name " +
+                            request.getS3StoGroupResourceProfile().getS3GroupResourceProfileName())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void updateS3StoGroupResourceProfile(S3StoGroupResourceProfileUpdateRequest request, StreamObserver<Empty> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("S3",
+                    request.getS3StoGroupResourceProfile().getS3GroupResourceProfileId(), request.getAuthzToken(), AccessLevel.WRITE);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for S3 group resource profile with id " +
+                                request.getS3StoGroupResourceProfile().getS3GroupResourceProfileId())
+                        .asRuntimeException());
+            }
+
+            boolean exists = groupResourceProfileRepository.existsById(
+                    request.getS3StoGroupResourceProfile().getS3GroupResourceProfileId());
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("S3 group resource profile with id " +
+                                request.getS3StoGroupResourceProfile().getS3GroupResourceProfileId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            groupResourceProfileRepository.save(mapper.map(request.getS3StoGroupResourceProfile(),
+                    S3StoGroupResourceProfileEntity.class));
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to update the S3 group resource profile with id {}",
+                    request.getS3StoGroupResourceProfile().getS3GroupResourceProfileId(), e);
+
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to update the S3 group resource profile with id " +
+                            request.getS3StoGroupResourceProfile().getS3GroupResourceProfileId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void removeS3StoGroupResourceProfile(S3StoGroupResourceProfileRemoveRequest request, StreamObserver<Empty> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("S3",
+                    request.getS3StoGroupResourceProfileId(), request.getAuthzToken(), AccessLevel.WRITE);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for S3 group resource profile with id " +
+                                request.getS3StoGroupResourceProfileId())
+                        .asRuntimeException());
+            }
+
+            boolean exists = groupResourceProfileRepository.existsById(request.getS3StoGroupResourceProfileId());
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("S3 group resource profile with id " + request.getS3StoGroupResourceProfileId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            groupResourceProfileRepository.deleteById(request.getS3StoGroupResourceProfileId());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to remove the S3 group resource profile with id {}", request.getS3StoGroupResourceProfileId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to remove the S3 group resource profile with id {} " + request.getS3StoGroupResourceProfileId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void fetchS3StoGroupResourceProfile(S3StoGroupResourceProfileFetchRequest request, StreamObserver<S3StoGroupResourceProfileFetchResponse> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("S3",
+                    request.getS3StoGroupResourceProfileId(), request.getAuthzToken(), AccessLevel.READ);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for S3 group resource profile with id " +
+                                request.getS3StoGroupResourceProfileId())
+                        .asRuntimeException());
+            }
+
+            boolean exists = groupResourceProfileRepository.existsById(request.getS3StoGroupResourceProfileId());
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("S3 group resource profile with id " + request.getS3StoGroupResourceProfileId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            Optional<S3StoGroupResourceProfileEntity> groupResProfOp = groupResourceProfileRepository.findById(request.getS3StoGroupResourceProfileId());
+
+            responseObserver.onNext(mapper.map(groupResProfOp.get(),
+                    S3StoGroupResourceProfileFetchResponse.newBuilder().getClass()).build());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to fetch the S3 group resource profile with id {}", request.getS3StoGroupResourceProfileId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to fetch the S3 group resource profile with id " + request.getS3StoGroupResourceProfileId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void listS3StoGroupResourceProfile(S3StoGroupResourceProfileListRequest request, StreamObserver<S3StoGroupResourceProfileListResponse> responseObserver) {
+        responseObserver.onError(Status.INTERNAL
+                .withDescription("Method not implemented")
+                .asRuntimeException());
+    }
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/handler/storage/SCPStorageHandler.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/handler/storage/SCPStorageHandler.java
new file mode 100644
index 0000000..8696a7b
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/handler/storage/SCPStorageHandler.java
@@ -0,0 +1,449 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.airavata.resource.profile.handler.storage;
+
+import com.google.protobuf.Empty;
+import io.grpc.Status;
+import io.grpc.stub.StreamObserver;
+import org.apache.airavata.resource.profile.service.s3.S3StorageCreateResponse;
+import org.apache.airavata.resource.profile.service.s3.S3StorageFetchResponse;
+import org.apache.airavata.resource.profile.service.scp.*;
+import org.apache.airavata.resource.profile.sharing.SharingImpl;
+import org.apache.airavata.resource.profile.storage.scp.entity.SCPStoGroupPreferenceEntity;
+import org.apache.airavata.resource.profile.storage.scp.entity.SCPStoGroupPreferenceId;
+import org.apache.airavata.resource.profile.storage.scp.entity.SCPStoGroupResourceProfileEntity;
+import org.apache.airavata.resource.profile.storage.scp.entity.SCPStorageEntity;
+import org.apache.airavata.resource.profile.storage.scp.repository.SCPStoGroupPreferenceRepository;
+import org.apache.airavata.resource.profile.storage.scp.repository.SCPStoGroupResourceProfileRepository;
+import org.apache.airavata.resource.profile.storage.scp.repository.SCPStorageRepository;
+import org.apache.airavata.resource.profile.stubs.s3.S3Storage;
+import org.apache.airavata.resource.profile.stubs.scp.SCPStorage;
+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.Optional;
+
+@GRpcService
+public class SCPStorageHandler extends SCPStorageServiceGrpc.SCPStorageServiceImplBase {
+
+    private static final Logger logger = LoggerFactory.getLogger(SCPStorageHandler.class);
+
+    @Autowired
+    private SCPStorageRepository storageRepository;
+
+    @Autowired
+    private SCPStoGroupPreferenceRepository groupPreferenceRepository;
+
+    @Autowired
+    private SCPStoGroupResourceProfileRepository groupResourceProfileRepository;
+
+    @Autowired
+    private SharingImpl sharingImpl;
+
+    private DozerBeanMapper mapper = new DozerBeanMapper();
+
+    @Override
+    public void createSCPStorage(SCPStorageCreateRequest request, StreamObserver<SCPStorageCreateResponse> responseObserver) {
+        try {
+            SCPStorageEntity savedEntity = storageRepository.save(mapper.map(request.getScpStorage(), SCPStorageEntity.class));
+
+            sharingImpl.createSharingEntity("SCP", savedEntity.getScpStorageId(), request.getAuthzToken(), SharingImpl.AccessLevel.WRITE);
+
+            SCPStorage savedStorage = mapper.map(savedEntity, SCPStorage.newBuilder().getClass()).build();
+            responseObserver.onNext(SCPStorageCreateResponse.newBuilder().setScpStorage(savedStorage).build());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to create the SCP Storage with host name {}", request.getScpStorage().getHostName(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to create the SCP Storage with host name " + request.getScpStorage().getHostName())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void updateSCPStorage(SCPStorageUpdateRequest request, StreamObserver<Empty> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("SCP",
+                    request.getScpStorage().getScpStorageId(), request.getAuthzToken(), SharingImpl.AccessLevel.WRITE);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for storage " + request.getScpStorage().getScpStorageId())
+                        .asRuntimeException());
+            }
+
+            boolean exists = storageRepository.existsById(request.getScpStorage().getScpStorageId());
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("SCP storage with id" + request.getScpStorage().getScpStorageId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            storageRepository.save(mapper.map(request.getScpStorage(), SCPStorageEntity.class));
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to update the SCP Storage with id {}", request.getScpStorage().getScpStorageId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to update the SCP Storage with id " + request.getScpStorage().getScpStorageId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void removeSCPStorage(SCPStorageRemoveRequest request, StreamObserver<Empty> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("SCP",
+                    request.getScpStorageId(), request.getAuthzToken(), SharingImpl.AccessLevel.WRITE);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for storage " + request.getScpStorageId())
+                        .asRuntimeException());
+            }
+
+            boolean exists = storageRepository.existsById(request.getScpStorageId());
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("SCP storage with id " + request.getScpStorageId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            storageRepository.deleteById(request.getScpStorageId());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to remove the SCP Storage with id {}", request.getScpStorageId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to remove the SCP Storage with id {} " + request.getScpStorageId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void fetchSCPStorage(SCPStorageFetchRequest request, StreamObserver<SCPStorageFetchResponse> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("SCP",
+                    request.getScpStorageId(), request.getAuthzToken(), SharingImpl.AccessLevel.READ);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for storage " + request.getScpStorageId())
+                        .asRuntimeException());
+            }
+
+            boolean exists = storageRepository.existsById(request.getScpStorageId());
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("SCP storage with id" + request.getScpStorageId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            Optional<SCPStorageEntity> storageEntityOp = storageRepository.findById(request.getScpStorageId());
+
+            SCPStorage fetchedStorage = mapper.map(storageEntityOp.get(), SCPStorage.newBuilder().getClass()).build();
+            responseObserver.onNext(SCPStorageFetchResponse.newBuilder().setScpStorage(fetchedStorage).build());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to fetch the SCP Storage with id {}", request.getScpStorageId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to fetch the SCP Storage with id " + request.getScpStorageId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void listSCPStorage(SCPStorageListRequest request, StreamObserver<SCPStorageListResponse> responseObserver) {
+        responseObserver.onError(Status.INTERNAL
+                .withDescription("Method not implemented")
+                .asRuntimeException());
+    }
+
+    @Override
+    public void createSCPStoGroupPreference(SCPStoGroupPreferenceCreateRequest request, StreamObserver<SCPStoGroupPreferenceCreateResponse> responseObserver) {
+        try {
+            SCPStoGroupPreferenceEntity savedEntity = groupPreferenceRepository.save(mapper.map(request.getScpStoGroupPreference(), SCPStoGroupPreferenceEntity.class));
+
+            sharingImpl.createSharingEntity("SCP",
+                    savedEntity.getScpStorageId() + "-" + savedEntity.getScpGroupResourceProfileId(),
+                    request.getAuthzToken(), SharingImpl.AccessLevel.WRITE);
+
+            responseObserver.onNext(mapper.map(savedEntity, SCPStoGroupPreferenceCreateResponse.newBuilder().getClass()).build());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to create the SCP storage group preference with storage id {}",
+                    request.getScpStoGroupPreference().getScpStorageId(), e);
+
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to create the SCP storage group preference with storage id " +
+                            request.getScpStoGroupPreference().getScpStorageId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void updateSCPStoGroupPreference(SCPStoGroupPreferenceUpdateRequest request, StreamObserver<Empty> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("SCP",
+                    request.getScpStoGroupPreference().getScpStorageId() + "-" + request.getScpStoGroupPreference().getScpGroupResourceProfileId(),
+                    request.getAuthzToken(), SharingImpl.AccessLevel.WRITE);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for storage group preference with storage id " +
+                                request.getScpStoGroupPreference().getScpStorageId())
+                        .asRuntimeException());
+            }
+
+            boolean exists = groupPreferenceRepository.existsById(new SCPStoGroupPreferenceId(
+                    request.getScpStoGroupPreference().getScpStorageId(),
+                    request.getScpStoGroupPreference().getScpGroupResourceProfileId()));
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("SCP storage with id" + request.getScpStoGroupPreference().getScpStorageId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            groupPreferenceRepository.save(mapper.map(request.getScpStoGroupPreference(), SCPStoGroupPreferenceEntity.class));
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to update the SCP Storage with id {}", request.getScpStoGroupPreference().getScpStorageId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to update the SCP Storage with id " + request.getScpStoGroupPreference().getScpStorageId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void removeSCPStoGroupPreference(SCPStoGroupPreferenceRemoveRequest request, StreamObserver<Empty> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("SCP",
+                    request.getScpStorageId() + "-" + request.getScpGroupResourceProfileId(),
+                    request.getAuthzToken(), SharingImpl.AccessLevel.WRITE);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for storage group preference with storage id  " +
+                                request.getScpStorageId())
+                        .asRuntimeException());
+            }
+
+            SCPStoGroupPreferenceId id = new SCPStoGroupPreferenceId(
+                    request.getScpStorageId(),
+                    request.getScpGroupResourceProfileId());
+
+            boolean exists = groupPreferenceRepository.existsById(id);
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("SCP storage group preference with storage id " + request.getScpStorageId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            groupPreferenceRepository.deleteById(id);
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to remove the SCP storage group preference with storage id {}", request.getScpStorageId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to remove the SCP storage group preference with storage id " + request.getScpStorageId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void fetchSCPStoGroupPreference(SCPStoGroupPreferenceFetchRequest request, StreamObserver<SCPStoGroupPreferenceFetchResponse> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("SCP",
+                    request.getScpStorageId() + "-" + request.getScpGroupResourceProfileId(),
+                    request.getAuthzToken(), SharingImpl.AccessLevel.WRITE);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for storage group preference with storage id  " +
+                                request.getScpStorageId())
+                        .asRuntimeException());
+            }
+
+            SCPStoGroupPreferenceId id = new SCPStoGroupPreferenceId(
+                    request.getScpStorageId(),
+                    request.getScpGroupResourceProfileId());
+
+            boolean exists = groupPreferenceRepository.existsById(id);
+
+            Optional<SCPStoGroupPreferenceEntity> groupPreferenceOp = groupPreferenceRepository.findById(id);
+
+            responseObserver.onNext(mapper.map(groupPreferenceOp.get(),
+                    SCPStoGroupPreferenceFetchResponse.newBuilder().getClass()).build());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to fetch the SCP storage group preference with storage id {}", request.getScpStorageId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to fetch the SCP storage group preference with storage id  " + request.getScpStorageId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void createSCPStoGroupResourceProfile(SCPStoGroupResourceProfileCreateRequest request, StreamObserver<SCPStoGroupResourceProfileCreateResponse> responseObserver) {
+        try {
+            SCPStoGroupResourceProfileEntity savedEntity = groupResourceProfileRepository.save(
+                    mapper.map(request.getScpStoGroupResourceProfile(), SCPStoGroupResourceProfileEntity.class));
+
+            sharingImpl.createSharingEntity("SCP", savedEntity.getScpGroupResourceProfileId(),
+                    request.getAuthzToken(), SharingImpl.AccessLevel.WRITE);
+
+            responseObserver.onNext(mapper.map(savedEntity,
+                    SCPStoGroupResourceProfileCreateResponse.newBuilder().getClass()).build());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to create the SCP group resource profile with name {}",
+                    request.getScpStoGroupResourceProfile().getScpGroupResourceProfileName(), e);
+
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to create the SCP group resource profile with name " +
+                            request.getScpStoGroupResourceProfile().getScpGroupResourceProfileName())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void updateSCPStoGroupResourceProfile(SCPStoGroupResourceProfileUpdateRequest request, StreamObserver<Empty> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("SCP",
+                    request.getScpStoGroupResourceProfile().getScpGroupResourceProfileId(), request.getAuthzToken(), SharingImpl.AccessLevel.WRITE);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for SCP group resource profile with id " +
+                                request.getScpStoGroupResourceProfile().getScpGroupResourceProfileId())
+                        .asRuntimeException());
+            }
+
+            boolean exists = groupResourceProfileRepository.existsById(
+                    request.getScpStoGroupResourceProfile().getScpGroupResourceProfileId());
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("SCP group resource profile with id " +
+                                request.getScpStoGroupResourceProfile().getScpGroupResourceProfileId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            groupResourceProfileRepository.save(mapper.map(request.getScpStoGroupResourceProfile(),
+                    SCPStoGroupResourceProfileEntity.class));
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to update the SCP group resource profile with id {}",
+                    request.getScpStoGroupResourceProfile().getScpGroupResourceProfileId(), e);
+
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to update the SCP group resource profile with id " +
+                            request.getScpStoGroupResourceProfile().getScpGroupResourceProfileId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void removeSCPStoGroupResourceProfile(SCPStoGroupResourceProfileRemoveRequest request, StreamObserver<Empty> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("SCP",
+                    request.getScpStoGroupResourceProfileId(), request.getAuthzToken(), SharingImpl.AccessLevel.WRITE);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for SCP group resource profile with id " +
+                                request.getScpStoGroupResourceProfileId())
+                        .asRuntimeException());
+            }
+
+            boolean exists = groupResourceProfileRepository.existsById(request.getScpStoGroupResourceProfileId());
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("SCP group resource profile with id " + request.getScpStoGroupResourceProfileId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            groupResourceProfileRepository.deleteById(request.getScpStoGroupResourceProfileId());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to remove the SCP group resource profile with id {}", request.getScpStoGroupResourceProfileId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to remove the SCP group resource profile with id {} " + request.getScpStoGroupResourceProfileId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void fetchSCPStoGroupResourceProfile(SCPStoGroupResourceProfileFetchRequest request, StreamObserver<SCPStoGroupResourceProfileFetchResponse> responseObserver) {
+        try {
+            boolean hasAccess = sharingImpl.hasAccess("SCP",
+                    request.getScpStoGroupResourceProfileId(), request.getAuthzToken(), SharingImpl.AccessLevel.READ);
+
+            if (!hasAccess) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("User does not have access for SCP group resource profile with id " +
+                                request.getScpStoGroupResourceProfileId())
+                        .asRuntimeException());
+            }
+
+            boolean exists = groupResourceProfileRepository.existsById(request.getScpStoGroupResourceProfileId());
+
+            if (!exists) {
+                responseObserver.onError(Status.INTERNAL
+                        .withDescription("SCP group resource profile with id " + request.getScpStoGroupResourceProfileId() + " does not exist")
+                        .asRuntimeException());
+            }
+
+            Optional<SCPStoGroupResourceProfileEntity> groupResProfOp = groupResourceProfileRepository.findById(request.getScpStoGroupResourceProfileId());
+
+            responseObserver.onNext(mapper.map(groupResProfOp.get(),
+                    SCPStoGroupResourceProfileFetchResponse.newBuilder().getClass()).build());
+            responseObserver.onCompleted();
+
+        } catch (Exception e) {
+            logger.error("Failed to fetch the SCP group resource profile with id {}", request.getScpStoGroupResourceProfileId(), e);
+            responseObserver.onError(Status.INTERNAL.withCause(e)
+                    .withDescription("Failed to fetch the SCP group resource profile with id " + request.getScpStoGroupResourceProfileId())
+                    .asRuntimeException());
+        }
+    }
+
+    @Override
+    public void listSCPStoGroupResourceProfile(SCPStoGroupResourceProfileListRequest request, StreamObserver<SCPStoGroupResourceProfileListResponse> responseObserver) {
+        responseObserver.onError(Status.INTERNAL
+                .withDescription("Method not implemented")
+                .asRuntimeException());
+    }
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/service/AppConfig.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/service/AppConfig.java
new file mode 100644
index 0000000..0adcaac
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/service/AppConfig.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.airavata.resource.profile.service;
+
+import org.apache.airavata.resource.profile.sharing.SharingImpl;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AppConfig {
+
+    @Bean
+    public SharingImpl sharingImpl() {
+        return new SharingImpl();
+    }
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/service/ResourceProfileServiceApplication.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/service/ResourceProfileServiceApplication.java
new file mode 100644
index 0000000..0e29aa4
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/service/ResourceProfileServiceApplication.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.airavata.resource.profile.service;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+
+@SpringBootApplication
+@ComponentScan(basePackages = {"org.apache.airavata.resource.profile"})
+@EnableJpaRepositories("org.apache.airavata.resource.profile.storage")
+@EntityScan("org.apache.airavata.resource.profile.storage")
+public class ResourceProfileServiceApplication {
+    public static void main(String args[]) {
+        SpringApplication.run(ResourceProfileServiceApplication.class, args);
+    }
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/service/SampleClient.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/service/SampleClient.java
new file mode 100644
index 0000000..ec9b221
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/service/SampleClient.java
@@ -0,0 +1,25 @@
+package org.apache.airavata.resource.profile.service;
+
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import org.apache.airavata.resource.profile.service.s3.*;
+import org.apache.airavata.resource.profile.stubs.common.AuthzToken;
+import org.apache.airavata.resource.profile.stubs.s3.S3Storage;
+
+public class SampleClient {
+    public static void main(String args[]) {
+        ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 17002).usePlaintext().build();
+
+
+
+        S3StorageServiceGrpc.S3StorageServiceBlockingStub s3StorageServiceBlockingStub = S3StorageServiceGrpc.newBlockingStub(channel);
+        S3StorageCreateResponse s3Storage = s3StorageServiceBlockingStub.createS3Storage(S3StorageCreateRequest.newBuilder()
+                .setAuthzToken(AuthzToken.newBuilder().setAuthorizationToken("token").build())
+                .setS3Storage(S3Storage.newBuilder().setBucketName("bucket-1").setRegion("us-east").build()).build());
+
+        System.out.println(s3Storage.getS3Storage());
+
+        S3StorageFetchResponse s3StorageFetchResponse = s3StorageServiceBlockingStub.fetchS3Storage(S3StorageFetchRequest.newBuilder().setS3StorageId(s3Storage.getS3Storage().getS3StorageId()).setAuthzToken(AuthzToken.newBuilder().setAuthorizationToken("token").build()).build());
+        System.out.println(s3StorageFetchResponse.getS3Storage());
+    }
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/service/XmlConfiguration.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/service/XmlConfiguration.java
new file mode 100644
index 0000000..f970c5a
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/service/XmlConfiguration.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.airavata.resource.profile.service;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.ImportResource;
+
+@Configuration
+@ImportResource({"applicationContext.xml"})
+public class XmlConfiguration {
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/sharing/SharingImpl.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/sharing/SharingImpl.java
new file mode 100644
index 0000000..06745d9
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/sharing/SharingImpl.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.airavata.resource.profile.sharing;
+
+import org.apache.airavata.resource.profile.stubs.common.AuthzToken;
+
+public class SharingImpl {
+
+    public enum AccessLevel {
+        READ, WRITE
+    }
+
+    public void createSharingEntity(String resourceType, String resourceId, AuthzToken authzToken, AccessLevel accessLevel) {
+        // TODO implement to talk to sharing service
+    }
+
+    public boolean hasAccess(String resourceType, String resourceId, AuthzToken authzToken, AccessLevel accessLevel) {
+        // TODO implement to talk to sharing service
+        return true;
+    }
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/entity/S3StoGroupPreferenceEntity.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/entity/S3StoGroupPreferenceEntity.java
new file mode 100644
index 0000000..df5bb54
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/entity/S3StoGroupPreferenceEntity.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.airavata.resource.profile.storage.s3.entity;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "S3_STORAGE_GROUP_PREFERENCE")
+@IdClass(S3StoGroupPreferenceId.class)
+public class S3StoGroupPreferenceEntity {
+
+    @Id
+    @Column(name = "S3_STORAGE_ID")
+    private String s3StorageId;
+
+    @Id
+    @Column(name = "S3_GROUP_RESOURCE_PROFILE_ID")
+    private String s3GroupResourceProfileId;
+
+    @Column(name = "RESOURCE_CS_TOKEN")
+    private String resourceSpecificCredentialToken;
+
+    @ManyToOne(targetEntity = S3StoGroupResourceProfileEntity.class, cascade = CascadeType.ALL)
+    @JoinColumn(name = "S3_GROUP_RESOURCE_PROFILE_ID", insertable = false, updatable = false)
+    private S3StoGroupResourceProfileEntity s3GroupResourceProfile;
+
+    @ManyToOne(targetEntity = S3StorageEntity.class, cascade = CascadeType.ALL)
+    @JoinColumn(name = "S3_STORAGE_ID", insertable = false, updatable = false)
+    private  S3StorageEntity s3Storage;
+
+    public String getS3StorageId() {
+        return s3StorageId;
+    }
+
+    public S3StoGroupPreferenceEntity setS3StorageId(String s3StorageId) {
+        this.s3StorageId = s3StorageId;
+        return this;
+    }
+
+    public String getS3GroupResourceProfileId() {
+        return s3GroupResourceProfileId;
+    }
+
+    public S3StoGroupPreferenceEntity setS3GroupResourceProfileId(String s3GroupResourceProfileId) {
+        this.s3GroupResourceProfileId = s3GroupResourceProfileId;
+        return this;
+    }
+
+    public String getResourceSpecificCredentialToken() {
+        return resourceSpecificCredentialToken;
+    }
+
+    public S3StoGroupPreferenceEntity setResourceSpecificCredentialToken(String resourceSpecificCredentialToken) {
+        this.resourceSpecificCredentialToken = resourceSpecificCredentialToken;
+        return this;
+    }
+
+    public S3StoGroupResourceProfileEntity getS3GroupResourceProfile() {
+        return s3GroupResourceProfile;
+    }
+
+    public S3StoGroupPreferenceEntity setS3GroupResourceProfile(S3StoGroupResourceProfileEntity s3GroupResourceProfile) {
+        this.s3GroupResourceProfile = s3GroupResourceProfile;
+        return this;
+    }
+
+    public S3StorageEntity getS3Storage() {
+        return s3Storage;
+    }
+
+    public S3StoGroupPreferenceEntity setS3Storage(S3StorageEntity s3Storage) {
+        this.s3Storage = s3Storage;
+        return this;
+    }
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/entity/S3StoGroupPreferenceId.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/entity/S3StoGroupPreferenceId.java
new file mode 100644
index 0000000..14a2459
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/entity/S3StoGroupPreferenceId.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.airavata.resource.profile.storage.s3.entity;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+public class S3StoGroupPreferenceId implements Serializable {
+    private String s3StorageId;
+    private String s3GroupResourceProfileId;
+
+    public S3StoGroupPreferenceId(String s3StorageId, String s3GroupResourceProfileId) {
+        this.s3StorageId = s3StorageId;
+        this.s3GroupResourceProfileId = s3GroupResourceProfileId;
+    }
+
+    public String getS3StorageId() {
+        return s3StorageId;
+    }
+
+    public S3StoGroupPreferenceId setS3StorageId(String s3StorageId) {
+        this.s3StorageId = s3StorageId;
+        return this;
+    }
+
+    public String getS3GroupResourceProfileId() {
+        return s3GroupResourceProfileId;
+    }
+
+    public S3StoGroupPreferenceId setS3GroupResourceProfileId(String s3GroupResourceProfileId) {
+        this.s3GroupResourceProfileId = s3GroupResourceProfileId;
+        return this;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof S3StoGroupPreferenceId)) return false;
+        S3StoGroupPreferenceId that = (S3StoGroupPreferenceId) o;
+        return Objects.equals(getS3StorageId(), that.getS3StorageId()) &&
+                Objects.equals(getS3GroupResourceProfileId(), that.getS3GroupResourceProfileId());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getS3StorageId(), getS3GroupResourceProfileId());
+    }
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/entity/S3StoGroupResourceProfileEntity.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/entity/S3StoGroupResourceProfileEntity.java
new file mode 100644
index 0000000..78b4c3d
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/entity/S3StoGroupResourceProfileEntity.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.airavata.resource.profile.storage.s3.entity;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Entity
+@Table(name = "S3_STORAGE_GROUP_RESOURCE_PROFILE")
+public class S3StoGroupResourceProfileEntity {
+
+    @Id
+    @Column(name = "S3_GROUP_RESOURCE_PROFILE_ID")
+    private String s3GroupResourceProfileId;
+
+    @Column(name = "GATEWAY_ID")
+    private String gatewayId;
+
+    @Column(name = "S3_GROUP_RESOURCE_PROFILE_NAME")
+    private String s3GroupResourceProfileName;
+
+    @Column(name = "CREATION_TIME", updatable = false)
+    private Long creationTime;
+
+    @Column(name = "UPDATE_TIME")
+    private Long updatedTime;
+
+    @Column(name = "DEFAULT_S3_CREDENTIAL_STORE_TOKEN")
+    private String defaultS3CredentialStoreToken;
+
+    @OneToMany(targetEntity = S3StoGroupPreferenceEntity.class, cascade = CascadeType.ALL,
+            mappedBy = "s3GroupResourceProfileId", fetch = FetchType.EAGER, orphanRemoval = true)
+    private List<S3StoGroupPreferenceEntity> s3StoragePreferences;
+
+    public String getS3GroupResourceProfileId() {
+        return s3GroupResourceProfileId;
+    }
+
+    public S3StoGroupResourceProfileEntity setS3GroupResourceProfileId(String s3GroupResourceProfileId) {
+        this.s3GroupResourceProfileId = s3GroupResourceProfileId;
+        return this;
+    }
+
+    public String getGatewayId() {
+        return gatewayId;
+    }
+
+    public S3StoGroupResourceProfileEntity setGatewayId(String gatewayId) {
+        this.gatewayId = gatewayId;
+        return this;
+    }
+
+    public String getS3GroupResourceProfileName() {
+        return s3GroupResourceProfileName;
+    }
+
+    public S3StoGroupResourceProfileEntity setS3GroupResourceProfileName(String s3GroupResourceProfileName) {
+        this.s3GroupResourceProfileName = s3GroupResourceProfileName;
+        return this;
+    }
+
+    public Long getCreationTime() {
+        return creationTime;
+    }
+
+    public S3StoGroupResourceProfileEntity setCreationTime(Long creationTime) {
+        this.creationTime = creationTime;
+        return this;
+    }
+
+    public Long getUpdatedTime() {
+        return updatedTime;
+    }
+
+    public S3StoGroupResourceProfileEntity setUpdatedTime(Long updatedTime) {
+        this.updatedTime = updatedTime;
+        return this;
+    }
+
+    public String getDefaultS3CredentialStoreToken() {
+        return defaultS3CredentialStoreToken;
+    }
+
+    public S3StoGroupResourceProfileEntity setDefaultS3CredentialStoreToken(String defaultS3CredentialStoreToken) {
+        this.defaultS3CredentialStoreToken = defaultS3CredentialStoreToken;
+        return this;
+    }
+
+    public List<S3StoGroupPreferenceEntity> getS3StoragePreferences() {
+        return s3StoragePreferences;
+    }
+
+    public S3StoGroupResourceProfileEntity setS3StoragePreferences(List<S3StoGroupPreferenceEntity> s3StoragePreferences) {
+        this.s3StoragePreferences = s3StoragePreferences;
+        return this;
+    }
+}
+
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/entity/S3StorageEntity.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/entity/S3StorageEntity.java
new file mode 100644
index 0000000..ce0ecc4
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/entity/S3StorageEntity.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.airavata.resource.profile.storage.s3.entity;
+
+import org.hibernate.annotations.GenericGenerator;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "S3_STORAGE_ENTITY")
+public class S3StorageEntity {
+
+    @Id
+    @GeneratedValue(generator = "UUID")
+    @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
+    @Column(name = "S3_STORAGE_ID")
+    private String s3StorageId;
+
+    @Column(name = "REGION")
+    private String region;
+
+    @Column(name = "BUCKET_NAME")
+    private String bucketName;
+
+    public String getS3StorageId() {
+        return s3StorageId;
+    }
+
+    public S3StorageEntity setS3StorageId(String s3StorageId) {
+        this.s3StorageId = s3StorageId;
+        return this;
+    }
+
+    public String getRegion() {
+        return region;
+    }
+
+    public S3StorageEntity setRegion(String region) {
+        this.region = region;
+        return this;
+    }
+
+    public String getBucketName() {
+        return bucketName;
+    }
+
+    public S3StorageEntity setBucketName(String bucketName) {
+        this.bucketName = bucketName;
+        return this;
+    }
+}
+
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/repository/S3StoGroupPreferenceRepository.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/repository/S3StoGroupPreferenceRepository.java
new file mode 100644
index 0000000..5573bd1
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/repository/S3StoGroupPreferenceRepository.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.airavata.resource.profile.storage.s3.repository;
+
+import org.apache.airavata.resource.profile.storage.s3.entity.S3StoGroupPreferenceEntity;
+import org.apache.airavata.resource.profile.storage.s3.entity.S3StoGroupPreferenceId;
+import org.springframework.data.repository.CrudRepository;
+
+public interface S3StoGroupPreferenceRepository extends CrudRepository<S3StoGroupPreferenceEntity, S3StoGroupPreferenceId> {
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/repository/S3StoGroupResourceProfileRepository.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/repository/S3StoGroupResourceProfileRepository.java
new file mode 100644
index 0000000..0719042
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/repository/S3StoGroupResourceProfileRepository.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.airavata.resource.profile.storage.s3.repository;
+
+import org.apache.airavata.resource.profile.storage.s3.entity.S3StoGroupResourceProfileEntity;
+import org.springframework.data.repository.CrudRepository;
+
+public interface S3StoGroupResourceProfileRepository extends CrudRepository<S3StoGroupResourceProfileEntity, String> {
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/repository/S3StorageRepository.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/repository/S3StorageRepository.java
new file mode 100644
index 0000000..1f9ad9d
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/s3/repository/S3StorageRepository.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.airavata.resource.profile.storage.s3.repository;
+
+import org.apache.airavata.resource.profile.storage.s3.entity.S3StorageEntity;
+import org.springframework.data.repository.CrudRepository;
+
+public interface S3StorageRepository extends CrudRepository<S3StorageEntity, String> {
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/entity/SCPStoGroupPreferenceEntity.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/entity/SCPStoGroupPreferenceEntity.java
new file mode 100644
index 0000000..4aa1cc9
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/entity/SCPStoGroupPreferenceEntity.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.airavata.resource.profile.storage.scp.entity;
+
+import javax.persistence.*;
+
+@Entity
+// TODO Add PK class
+@Table(name = "SCP_STORAGE_GROUP_PREFERENCE")
+@IdClass(SCPStoGroupPreferenceId.class)
+public class SCPStoGroupPreferenceEntity {
+
+    @Id
+    @Column(name = "SCP_STORAGE_ID")
+    private String scpStorageId;
+
+    @Id
+    @Column(name = "SCP_GROUP_RESOURCE_PROFILE_ID")
+    private String scpGroupResourceProfileId;
+
+    @Column(name = "LOGIN_USER_NAME")
+    private String loginUserName;
+
+    @Column(name = "RESOURCE_CS_TOKEN")
+    private String resourceSpecificCredentialToken;
+
+    @ManyToOne(targetEntity = SCPStoGroupResourceProfileEntity.class, cascade = CascadeType.ALL)
+    @JoinColumn(name = "SCP_GROUP_RESOURCE_PROFILE_ID", insertable = false, updatable = false)
+    private SCPStoGroupResourceProfileEntity scpGroupResourceProfile;
+
+
+    @ManyToOne(targetEntity = SCPStorageEntity.class, cascade = CascadeType.ALL)
+    @JoinColumn(name = "SCP_STORAGE_ID", insertable = false, updatable = false)
+    private  SCPStorageEntity scpStorage;
+
+    public String getScpStorageId() {
+        return scpStorageId;
+    }
+
+    public SCPStoGroupPreferenceEntity setScpStorageId(String scpStorageId) {
+        this.scpStorageId = scpStorageId;
+        return this;
+    }
+
+    public String getScpGroupResourceProfileId() {
+        return scpGroupResourceProfileId;
+    }
+
+    public SCPStoGroupPreferenceEntity setScpGroupResourceProfileId(String scpGroupResourceProfileId) {
+        this.scpGroupResourceProfileId = scpGroupResourceProfileId;
+        return this;
+    }
+
+    public String getLoginUserName() {
+        return loginUserName;
+    }
+
+    public SCPStoGroupPreferenceEntity setLoginUserName(String loginUserName) {
+        this.loginUserName = loginUserName;
+        return this;
+    }
+
+    public String getResourceSpecificCredentialToken() {
+        return resourceSpecificCredentialToken;
+    }
+
+    public SCPStoGroupPreferenceEntity setResourceSpecificCredentialToken(String resourceSpecificCredentialToken) {
+        this.resourceSpecificCredentialToken = resourceSpecificCredentialToken;
+        return this;
+    }
+
+    public SCPStoGroupResourceProfileEntity getScpGroupResourceProfile() {
+        return scpGroupResourceProfile;
+    }
+
+    public SCPStoGroupPreferenceEntity setScpGroupResourceProfile(SCPStoGroupResourceProfileEntity scpGroupResourceProfile) {
+        this.scpGroupResourceProfile = scpGroupResourceProfile;
+        return this;
+    }
+
+    public SCPStorageEntity getScpStorage() {
+        return scpStorage;
+    }
+
+    public SCPStoGroupPreferenceEntity setScpStorage(SCPStorageEntity scpStorage) {
+        this.scpStorage = scpStorage;
+        return this;
+    }
+}
+
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/entity/SCPStoGroupPreferenceId.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/entity/SCPStoGroupPreferenceId.java
new file mode 100644
index 0000000..2d181b8
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/entity/SCPStoGroupPreferenceId.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.airavata.resource.profile.storage.scp.entity;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+public class SCPStoGroupPreferenceId implements Serializable {
+
+    private String scpStorageId;
+    private String scpGroupResourceProfileId;
+
+    public SCPStoGroupPreferenceId(String scpStorageId, String scpGroupResourceProfileId) {
+        this.scpStorageId = scpStorageId;
+        this.scpGroupResourceProfileId = scpGroupResourceProfileId;
+    }
+
+    public String getScpStorageId() {
+        return scpStorageId;
+    }
+
+    public SCPStoGroupPreferenceId setScpStorageId(String scpStorageId) {
+        this.scpStorageId = scpStorageId;
+        return this;
+    }
+
+    public String getScpGroupResourceProfileId() {
+        return scpGroupResourceProfileId;
+    }
+
+    public SCPStoGroupPreferenceId setScpGroupResourceProfileId(String scpGroupResourceProfileId) {
+        this.scpGroupResourceProfileId = scpGroupResourceProfileId;
+        return this;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof SCPStoGroupPreferenceId)) return false;
+        SCPStoGroupPreferenceId that = (SCPStoGroupPreferenceId) o;
+        return Objects.equals(getScpStorageId(), that.getScpStorageId()) &&
+                Objects.equals(getScpGroupResourceProfileId(), that.getScpGroupResourceProfileId());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getScpStorageId(), getScpGroupResourceProfileId());
+    }
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/entity/SCPStoGroupResourceProfileEntity.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/entity/SCPStoGroupResourceProfileEntity.java
new file mode 100644
index 0000000..64df304
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/entity/SCPStoGroupResourceProfileEntity.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.airavata.resource.profile.storage.scp.entity;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Entity
+@Table(name = "SCP_STORAGE_GROUP_RESOURCE_PROFILE")
+public class SCPStoGroupResourceProfileEntity {
+
+    @Id
+    @Column(name = "SCP_GROUP_RESOURCE_PROFILE_ID")
+    private String scpGroupResourceProfileId;
+
+    @Column(name = "GATEWAY_ID")
+    private String gatewayId;
+
+    @Column(name = "SCP_GROUP_RESOURCE_PROFILE_NAME")
+    private String scpGroupResourceProfileName;
+
+    @Column(name = "CREATION_TIME", updatable = false)
+    private Long creationTime;
+
+    @Column(name = "UPDATE_TIME")
+    private Long updatedTime;
+
+    @Column(name = "DEFAULT_SCP_CREDENTIAL_STORE_TOKEN")
+    private String defaultSCPCredentialStoreToken;
+
+    @OneToMany(targetEntity = SCPStoGroupPreferenceEntity.class, cascade = CascadeType.ALL,
+            mappedBy = "scpGroupResourceProfileId", fetch = FetchType.EAGER, orphanRemoval = true)
+    private List<SCPStoGroupPreferenceEntity> scpStoragePreferences;
+
+    public String getScpGroupResourceProfileId() {
+        return scpGroupResourceProfileId;
+    }
+
+    public SCPStoGroupResourceProfileEntity setScpGroupResourceProfileId(String scpGroupResourceProfileId) {
+        this.scpGroupResourceProfileId = scpGroupResourceProfileId;
+        return this;
+    }
+
+    public String getGatewayId() {
+        return gatewayId;
+    }
+
+    public SCPStoGroupResourceProfileEntity setGatewayId(String gatewayId) {
+        this.gatewayId = gatewayId;
+        return this;
+    }
+
+    public String getScpGroupResourceProfileName() {
+        return scpGroupResourceProfileName;
+    }
+
+    public SCPStoGroupResourceProfileEntity setScpGroupResourceProfileName(String scpGroupResourceProfileName) {
+        this.scpGroupResourceProfileName = scpGroupResourceProfileName;
+        return this;
+    }
+
+    public Long getCreationTime() {
+        return creationTime;
+    }
+
+    public SCPStoGroupResourceProfileEntity setCreationTime(Long creationTime) {
+        this.creationTime = creationTime;
+        return this;
+    }
+
+    public Long getUpdatedTime() {
+        return updatedTime;
+    }
+
+    public SCPStoGroupResourceProfileEntity setUpdatedTime(Long updatedTime) {
+        this.updatedTime = updatedTime;
+        return this;
+    }
+
+    public String getDefaultSCPCredentialStoreToken() {
+        return defaultSCPCredentialStoreToken;
+    }
+
+    public SCPStoGroupResourceProfileEntity setDefaultSCPCredentialStoreToken(String defaultSCPCredentialStoreToken) {
+        this.defaultSCPCredentialStoreToken = defaultSCPCredentialStoreToken;
+        return this;
+    }
+
+    public List<SCPStoGroupPreferenceEntity> getScpStoragePreferences() {
+        return scpStoragePreferences;
+    }
+
+    public SCPStoGroupResourceProfileEntity setScpStoragePreferences(List<SCPStoGroupPreferenceEntity> scpStoragePreferences) {
+        this.scpStoragePreferences = scpStoragePreferences;
+        return this;
+    }
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/entity/SCPStorageEntity.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/entity/SCPStorageEntity.java
new file mode 100644
index 0000000..d1db065
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/entity/SCPStorageEntity.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.airavata.resource.profile.storage.scp.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "SCP_STORAGE_ENTITY")
+public class SCPStorageEntity {
+
+    @Id
+    @Column(name = "SCP_STORAGE_ID")
+    private String scpStorageId;
+
+    @Column(name = "HOST_NAME")
+    private String hostName;
+
+    @Column(name = "PORT")
+    private String port;
+
+    public String getScpStorageId() {
+        return scpStorageId;
+    }
+
+    public SCPStorageEntity setScpStorageId(String scpStorageId) {
+        this.scpStorageId = scpStorageId;
+        return this;
+    }
+
+    public String getHostName() {
+        return hostName;
+    }
+
+    public SCPStorageEntity setHostName(String hostName) {
+        this.hostName = hostName;
+        return this;
+    }
+
+    public String getPort() {
+        return port;
+    }
+
+    public SCPStorageEntity setPort(String port) {
+        this.port = port;
+        return this;
+    }
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/repository/SCPStoGroupPreferenceRepository.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/repository/SCPStoGroupPreferenceRepository.java
new file mode 100644
index 0000000..320638f
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/repository/SCPStoGroupPreferenceRepository.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.airavata.resource.profile.storage.scp.repository;
+
+import org.apache.airavata.resource.profile.storage.scp.entity.SCPStoGroupPreferenceEntity;
+import org.apache.airavata.resource.profile.storage.scp.entity.SCPStoGroupPreferenceId;
+import org.springframework.data.repository.CrudRepository;
+
+public interface SCPStoGroupPreferenceRepository extends CrudRepository<SCPStoGroupPreferenceEntity, SCPStoGroupPreferenceId> {
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/repository/SCPStoGroupResourceProfileRepository.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/repository/SCPStoGroupResourceProfileRepository.java
new file mode 100644
index 0000000..7049f4d
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/repository/SCPStoGroupResourceProfileRepository.java
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.airavata.resource.profile.storage.scp.repository;
+
+import org.apache.airavata.resource.profile.storage.scp.entity.SCPStoGroupResourceProfileEntity;
+import org.springframework.data.repository.CrudRepository;
+
+public interface SCPStoGroupResourceProfileRepository extends CrudRepository<SCPStoGroupResourceProfileEntity, String> {
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/repository/SCPStorageRepository.java b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/repository/SCPStorageRepository.java
new file mode 100644
index 0000000..ba82e59
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/java/org/apache/airavata/resource/profile/storage/scp/repository/SCPStorageRepository.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.airavata.resource.profile.storage.scp.repository;
+
+import org.apache.airavata.resource.profile.storage.scp.entity.SCPStorageEntity;
+import org.springframework.data.repository.CrudRepository;
+
+public interface SCPStorageRepository extends CrudRepository<SCPStorageEntity, String> {
+}
diff --git a/modules/resource-profile/resource-profile-service/src/main/resources/application.properties b/modules/resource-profile/resource-profile-service/src/main/resources/application.properties
new file mode 100644
index 0000000..56db2de
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+server.port=18080
+grpc.port=17002
\ No newline at end of file
diff --git a/modules/resource-profile/resource-profile-service/src/main/resources/applicationContext.xml b/modules/resource-profile/resource-profile-service/src/main/resources/applicationContext.xml
new file mode 100644
index 0000000..bb7b7cb
--- /dev/null
+++ b/modules/resource-profile/resource-profile-service/src/main/resources/applicationContext.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd
+        http://www.springframework.org/schema/context
+        http://www.springframework.org/schema/context/spring-context.xsd">
+
+
+</beans>
\ No newline at end of file
diff --git a/modules/resource-profile/resource-profile-stubs/pom.xml b/modules/resource-profile/resource-profile-stubs/pom.xml
new file mode 100644
index 0000000..0a62f1e
--- /dev/null
+++ b/modules/resource-profile/resource-profile-stubs/pom.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>resource-profile</artifactId>
+        <groupId>org.apache.airavata</groupId>
+        <version>0.21-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>resource-profile-stubs</artifactId>
+
+    <properties>
+        <maven.compiler.source>11</maven.compiler.source>
+        <maven.compiler.target>11</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+            <version>${protobuf.java}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-services</artifactId>
+            <version>1.35.0</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.google.code.gson</groupId>
+                    <artifactId>gson</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+            <version>${javax.annotation}</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+                <version>${os.maven.plugin}</version>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <version>${protobuf.maven.plugin}</version>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.0.2:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.1:exe:${os.detected.classifier}</pluginArtifact>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/modules/resource-profile/resource-profile-stubs/src/main/proto/common.proto b/modules/resource-profile/resource-profile-stubs/src/main/proto/common.proto
new file mode 100644
index 0000000..5557d8c
--- /dev/null
+++ b/modules/resource-profile/resource-profile-stubs/src/main/proto/common.proto
@@ -0,0 +1,8 @@
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.airavata.resource.profile.stubs.common;
+
+message AuthzToken {
+    string authorizationToken = 1;
+}
\ No newline at end of file
diff --git a/modules/resource-profile/resource-profile-stubs/src/main/proto/storage/s3/service.proto b/modules/resource-profile/resource-profile-stubs/src/main/proto/storage/s3/service.proto
new file mode 100644
index 0000000..c6cdafd
--- /dev/null
+++ b/modules/resource-profile/resource-profile-stubs/src/main/proto/storage/s3/service.proto
@@ -0,0 +1,158 @@
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.airavata.resource.profile.service.s3;
+
+import "google/api/annotations.proto";
+import "google/protobuf/empty.proto";
+import "storage/s3/stubs.proto";
+import "common.proto";
+
+/// S3Storage ///
+
+message S3StorageCreateRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    org.apache.airavata.resource.profile.stubs.s3.S3Storage s3Storage = 2;
+}
+
+message S3StorageCreateResponse {
+    org.apache.airavata.resource.profile.stubs.s3.S3Storage s3Storage = 1;
+}
+
+message S3StorageUpdateRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    org.apache.airavata.resource.profile.stubs.s3.S3Storage s3Storage = 2;
+}
+
+message S3StorageRemoveRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string s3StorageId = 2;
+}
+
+message S3StorageFetchRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string s3StorageId = 2;
+}
+
+message S3StorageFetchResponse {
+    org.apache.airavata.resource.profile.stubs.s3.S3Storage s3Storage = 1;
+}
+
+message S3StorageListRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string filterQuery = 2;
+}
+
+message S3StorageListResponse {
+    repeated org.apache.airavata.resource.profile.stubs.s3.S3Storage s3Storages = 1;
+}
+
+/// S3StoGroupPreference ///
+
+message S3StoGroupPreferenceCreateRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    org.apache.airavata.resource.profile.stubs.s3.S3StoGroupPreference s3StoGroupPreference = 2;
+}
+
+message S3StoGroupPreferenceCreateResponse {
+    org.apache.airavata.resource.profile.stubs.s3.S3StoGroupPreference s3StoGroupPreference = 1;
+}
+
+message S3StoGroupPreferenceUpdateRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    org.apache.airavata.resource.profile.stubs.s3.S3StoGroupPreference s3StoGroupPreference = 2;
+}
+
+message S3StoGroupPreferenceRemoveRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string s3StorageId = 2;
+    string s3GroupResourceProfileId = 3;
+}
+
+message S3StoGroupPreferenceFetchRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string s3StorageId = 2;
+    string s3GroupResourceProfileId = 3;
+}
+
+message S3StoGroupPreferenceFetchResponse {
+    org.apache.airavata.resource.profile.stubs.s3.S3StoGroupPreference s3StoGroupPreference = 1;
+}
+
+/// S3StoGroupResourceProfile ///
+
+message S3StoGroupResourceProfileCreateRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    org.apache.airavata.resource.profile.stubs.s3.S3StoGroupResourceProfile s3StoGroupResourceProfile = 2;
+}
+
+message S3StoGroupResourceProfileCreateResponse {
+    org.apache.airavata.resource.profile.stubs.s3.S3StoGroupResourceProfile s3StoGroupResourceProfile = 1;
+}
+
+message S3StoGroupResourceProfileUpdateRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    org.apache.airavata.resource.profile.stubs.s3.S3StoGroupResourceProfile s3StoGroupResourceProfile = 2;
+}
+
+message S3StoGroupResourceProfileRemoveRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string s3StoGroupResourceProfileId = 2;
+}
+
+message S3StoGroupResourceProfileFetchRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string s3StoGroupResourceProfileId = 2;
+}
+
+message S3StoGroupResourceProfileFetchResponse {
+    org.apache.airavata.resource.profile.stubs.s3.S3StoGroupResourceProfile s3StoGroupResourceProfile = 1;
+}
+
+message S3StoGroupResourceProfileListRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string filterQuery = 2;
+}
+
+message S3StoGroupResourceProfileListResponse {
+    repeated org.apache.airavata.resource.profile.stubs.s3.S3StoGroupResourceProfile s3StoGroupResourceProfiles = 1;
+}
+
+service S3StorageService {
+
+    /// S3Storage ///
+
+    rpc createS3Storage (S3StorageCreateRequest) returns (S3StorageCreateResponse) {};
+
+    rpc updateS3Storage (S3StorageUpdateRequest) returns (google.protobuf.Empty) {};
+
+    rpc removeS3Storage (S3StorageRemoveRequest) returns (google.protobuf.Empty) {};
+
+    rpc fetchS3Storage (S3StorageFetchRequest) returns (S3StorageFetchResponse) {};
+
+    rpc listS3Storage (S3StorageListRequest) returns (S3StorageListResponse) {};
+
+    /// S3StoGroupPreference ///
+
+    rpc createS3StoGroupPreference (S3StoGroupPreferenceCreateRequest) returns (S3StoGroupPreferenceCreateResponse) {};
+
+    rpc updateS3StoGroupPreference (S3StoGroupPreferenceUpdateRequest) returns (google.protobuf.Empty) {};
+
+    rpc removeS3StoGroupPreference (S3StoGroupPreferenceRemoveRequest) returns (google.protobuf.Empty) {};
+
+    rpc fetchS3StoGroupPreference (S3StoGroupPreferenceFetchRequest) returns (S3StoGroupPreferenceFetchResponse) {};
+
+    /// S3StoGroupResourceProfile ///
+
+    rpc createS3StoGroupResourceProfile (S3StoGroupResourceProfileCreateRequest) returns (S3StoGroupResourceProfileCreateResponse) {};
+
+    rpc updateS3StoGroupResourceProfile (S3StoGroupResourceProfileUpdateRequest) returns (google.protobuf.Empty) {};
+
+    rpc removeS3StoGroupResourceProfile (S3StoGroupResourceProfileRemoveRequest) returns (google.protobuf.Empty) {};
+
+    rpc fetchS3StoGroupResourceProfile (S3StoGroupResourceProfileFetchRequest) returns (S3StoGroupResourceProfileFetchResponse) {};
+
+    rpc listS3StoGroupResourceProfile (S3StoGroupResourceProfileListRequest) returns (S3StoGroupResourceProfileListResponse) {};
+}
+
+
diff --git a/modules/resource-profile/resource-profile-stubs/src/main/proto/storage/s3/stubs.proto b/modules/resource-profile/resource-profile-stubs/src/main/proto/storage/s3/stubs.proto
new file mode 100644
index 0000000..dfc7ce4
--- /dev/null
+++ b/modules/resource-profile/resource-profile-stubs/src/main/proto/storage/s3/stubs.proto
@@ -0,0 +1,26 @@
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.airavata.resource.profile.stubs.s3;
+
+message S3Storage {
+    optional string s3StorageId = 1;
+    string region = 2;
+    string bucketName = 3;
+}
+
+message S3StoGroupPreference {
+    string s3StorageId = 1;
+    string s3GroupResourceProfileId = 2;
+    string resourceSpecificCredentialToken = 3;
+}
+
+message S3StoGroupResourceProfile {
+    string s3GroupResourceProfileId = 1;
+    string gatewayId = 2;
+    string s3GroupResourceProfileName = 3;
+    int64 creationTime = 4;
+    int64 updatedTime = 5;
+    string defaultS3CredentialStoreToken = 6;
+    repeated S3StoGroupPreference s3StoragePreferences = 7;
+}
\ No newline at end of file
diff --git a/modules/resource-profile/resource-profile-stubs/src/main/proto/storage/scp/service.proto b/modules/resource-profile/resource-profile-stubs/src/main/proto/storage/scp/service.proto
new file mode 100644
index 0000000..f5b0960
--- /dev/null
+++ b/modules/resource-profile/resource-profile-stubs/src/main/proto/storage/scp/service.proto
@@ -0,0 +1,158 @@
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.airavata.resource.profile.service.scp;
+
+import "google/api/annotations.proto";
+import "google/protobuf/empty.proto";
+import "storage/scp/stubs.proto";
+import "common.proto";
+
+/// SCPStorage ///
+
+message SCPStorageCreateRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    org.apache.airavata.resource.profile.stubs.scp.SCPStorage scpStorage = 2;
+}
+
+message SCPStorageCreateResponse {
+    org.apache.airavata.resource.profile.stubs.scp.SCPStorage scpStorage = 1;
+}
+
+message SCPStorageUpdateRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    org.apache.airavata.resource.profile.stubs.scp.SCPStorage scpStorage = 2;
+}
+
+message SCPStorageRemoveRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string scpStorageId = 2;
+}
+
+message SCPStorageFetchRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string scpStorageId = 2;
+}
+
+message SCPStorageFetchResponse {
+    org.apache.airavata.resource.profile.stubs.scp.SCPStorage scpStorage = 1;
+}
+
+message SCPStorageListRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string filterQuery = 2;
+}
+
+message SCPStorageListResponse {
+    repeated org.apache.airavata.resource.profile.stubs.scp.SCPStorage scpStorages = 1;
+}
+
+/// SCPStoGroupPreference ///
+
+message SCPStoGroupPreferenceCreateRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    org.apache.airavata.resource.profile.stubs.scp.SCPStoGroupPreference scpStoGroupPreference = 2;
+}
+
+message SCPStoGroupPreferenceCreateResponse {
+    org.apache.airavata.resource.profile.stubs.scp.SCPStoGroupPreference scpStoGroupPreference = 1;
+}
+
+message SCPStoGroupPreferenceUpdateRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    org.apache.airavata.resource.profile.stubs.scp.SCPStoGroupPreference scpStoGroupPreference = 2;
+}
+
+message SCPStoGroupPreferenceRemoveRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string scpStorageId = 2;
+    string scpGroupResourceProfileId = 3;
+}
+
+message SCPStoGroupPreferenceFetchRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string scpStorageId = 2;
+    string scpGroupResourceProfileId = 3;
+}
+
+message SCPStoGroupPreferenceFetchResponse {
+    org.apache.airavata.resource.profile.stubs.scp.SCPStoGroupPreference scpStoGroupPreference = 1;
+}
+
+/// SCPStoGroupResourceProfile ///
+
+message SCPStoGroupResourceProfileCreateRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    org.apache.airavata.resource.profile.stubs.scp.SCPStoGroupResourceProfile scpStoGroupResourceProfile = 2;
+}
+
+message SCPStoGroupResourceProfileCreateResponse {
+    org.apache.airavata.resource.profile.stubs.scp.SCPStoGroupResourceProfile scpStoGroupResourceProfile = 1;
+}
+
+message SCPStoGroupResourceProfileUpdateRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    org.apache.airavata.resource.profile.stubs.scp.SCPStoGroupResourceProfile scpStoGroupResourceProfile = 2;
+}
+
+message SCPStoGroupResourceProfileRemoveRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string scpStoGroupResourceProfileId = 2;
+}
+
+message SCPStoGroupResourceProfileFetchRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string scpStoGroupResourceProfileId = 2;
+}
+
+message SCPStoGroupResourceProfileFetchResponse {
+    org.apache.airavata.resource.profile.stubs.scp.SCPStoGroupResourceProfile scpStoGroupResourceProfile = 1;
+}
+
+message SCPStoGroupResourceProfileListRequest {
+    org.apache.airavata.resource.profile.stubs.common.AuthzToken authzToken = 1;
+    string filterQuery = 2;
+}
+
+message SCPStoGroupResourceProfileListResponse {
+    repeated org.apache.airavata.resource.profile.stubs.scp.SCPStoGroupResourceProfile scpStoGroupResourceProfiles = 1;
+}
+
+service SCPStorageService {
+
+    /// SCPStorage ///
+
+    rpc createSCPStorage (SCPStorageCreateRequest) returns (SCPStorageCreateResponse) {};
+
+    rpc updateSCPStorage (SCPStorageUpdateRequest) returns (google.protobuf.Empty) {};
+
+    rpc removeSCPStorage (SCPStorageRemoveRequest) returns (google.protobuf.Empty) {};
+
+    rpc fetchSCPStorage (SCPStorageFetchRequest) returns (SCPStorageFetchResponse) {};
+
+    rpc listSCPStorage (SCPStorageListRequest) returns (SCPStorageListResponse) {};
+
+    /// SCPStoGroupPreference ///
+
+    rpc createSCPStoGroupPreference (SCPStoGroupPreferenceCreateRequest) returns (SCPStoGroupPreferenceCreateResponse) {};
+
+    rpc updateSCPStoGroupPreference (SCPStoGroupPreferenceUpdateRequest) returns (google.protobuf.Empty) {};
+
+    rpc removeSCPStoGroupPreference (SCPStoGroupPreferenceRemoveRequest) returns (google.protobuf.Empty) {};
+
+    rpc fetchSCPStoGroupPreference (SCPStoGroupPreferenceFetchRequest) returns (SCPStoGroupPreferenceFetchResponse) {};
+
+    /// SCPStoGroupResourceProfile ///
+
+    rpc createSCPStoGroupResourceProfile (SCPStoGroupResourceProfileCreateRequest) returns (SCPStoGroupResourceProfileCreateResponse) {};
+
+    rpc updateSCPStoGroupResourceProfile (SCPStoGroupResourceProfileUpdateRequest) returns (google.protobuf.Empty) {};
+
+    rpc removeSCPStoGroupResourceProfile (SCPStoGroupResourceProfileRemoveRequest) returns (google.protobuf.Empty) {};
+
+    rpc fetchSCPStoGroupResourceProfile (SCPStoGroupResourceProfileFetchRequest) returns (SCPStoGroupResourceProfileFetchResponse) {};
+
+    rpc listSCPStoGroupResourceProfile (SCPStoGroupResourceProfileListRequest) returns (SCPStoGroupResourceProfileListResponse) {};
+}
+
+
diff --git a/modules/resource-profile/resource-profile-stubs/src/main/proto/storage/scp/stubs.proto b/modules/resource-profile/resource-profile-stubs/src/main/proto/storage/scp/stubs.proto
new file mode 100644
index 0000000..b8cc0ad
--- /dev/null
+++ b/modules/resource-profile/resource-profile-stubs/src/main/proto/storage/scp/stubs.proto
@@ -0,0 +1,27 @@
+syntax = "proto3";
+
+option java_multiple_files = true;
+package org.apache.airavata.resource.profile.stubs.scp;
+
+message SCPStorage {
+    string scpStorageId = 1;
+    string hostName = 2;
+    int32 port = 3;
+}
+
+message SCPStoGroupPreference {
+    string scpStorageId = 1;
+    string scpGroupResourceProfileId = 2;
+    string loginUserName = 3;
+    string resourceSpecificCredentialToken = 4;
+}
+
+message SCPStoGroupResourceProfile {
+    string scpGroupResourceProfileId = 1;
+    string gatewayId = 2;
+    string scpGroupResourceProfileName = 3;
+    int64 creationTime = 4;
+    int64 updatedTime = 5;
+    string defaultSCPCredentialStoreToken = 6;
+    repeated SCPStoGroupPreference scpStoragePreferences = 7;
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 1979fef..5f017be 100644
--- a/pom.xml
+++ b/pom.xml
@@ -590,13 +590,7 @@
                             </execution>
                         </executions>
                     </plugin>
-		    <plugin>
-		       <groupId>org.apache.maven.plugins</groupId>
-		       <artifactId>maven-jar-plugins</artifactId>
-		       <version>${openjpa.version}</version>
-		    </plugin>
-		    
-		    <plugin>
+		            <plugin>
                         <groupId>com.lukegb.mojo</groupId>
                         <artifactId>gitdescribe-maven-plugin</artifactId>
                         <version>3.0</version>
@@ -784,6 +778,7 @@
                 <module>modules/compute-account-provisioning</module>
                 <module>modules/job-monitor</module>
                 <module>modules/platform-monitoring</module>
+                <module>modules/resource-profile</module>
                 <module>modules/distribution</module>
                 <module>tools</module>
                 <module>modules/ide-integration</module>