You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by aa...@apache.org on 2020/06/16 20:38:42 UTC

[airavata-mft-portal] 03/26: mft django portal project structure

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

aarushi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata-mft-portal.git

commit 6907ead30bc03e566dbd6764747bea3a6738a643
Author: Aarushi Bisht <aa...@gmail.com>
AuthorDate: Sun Apr 5 17:27:11 2020 -0400

    mft django portal project structure
---
 .gitignore                                         |   4 +
 README                                             |  17 +
 airavata_mft/__init__.py                           |   0
 airavata_mft/asgi.py                               |  16 +
 airavata_mft/settings.py                           | 125 ++++
 airavata_mft/static/base.css                       | 101 +++
 airavata_mft/templates/base.html                   |  89 +++
 airavata_mft/urls.py                               |  22 +
 airavata_mft/wsgi.py                               |  16 +
 apps/__init__.py                                   |   0
 apps/mft_agents/__init__.py                        |   0
 apps/mft_agents/admin.py                           |   3 +
 apps/mft_agents/apps.py                            |   5 +
 apps/mft_agents/migrations/__init__.py             |   0
 apps/mft_agents/models.py                          |   3 +
 .../templates/mft_agents/agents_list.html          |  15 +
 apps/mft_agents/tests.py                           |   3 +
 apps/mft_agents/urls.py                            |   5 +
 apps/mft_agents/views.py                           |  21 +
 gen_grpc_protos.ps1                                |   9 +
 gen_grpc_protos.sh                                 |  12 +
 manage.py                                          |  24 +
 mft_backend/__init__.py                            |   0
 mft_backend/resource_service/ClientStub.py         |  61 ++
 .../resource_service/ResourceService_pb2.py        | 826 +++++++++++++++++++++
 .../resource_service/ResourceService_pb2_grpc.py   | 236 ++++++
 mft_backend/resource_service/__init__.py           |   0
 requirements.txt                                   |   4 +
 28 files changed, 1617 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4840128
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+.idea/
+venv/
+**/__pycache__/
+db.sqlite3
diff --git a/README b/README
index 4be1253..bae34cd 100644
--- a/README
+++ b/README
@@ -1,3 +1,20 @@
 # Portal for Airavata Managed File Transfer
 
 Airavata Managed File Transfer is a standalone service to orchestrate data movement between various cloud and high performance computing storages. The MFT Portal provides a dashboard to monitor and users to request the transfers. 
+
+## Getting Started
+
+1.  Checkout this project and create a virtual environment.
+
+    ```
+    cd airavata-mft-portal
+    python3 -m venv venv
+    source venv/bin/activate
+    pip install -r requirements.txt
+    ```
+2.  Run the server
+
+    ```
+    python manage.py runserver
+    ```
+3. Point your browser to http://localhost:8000/agents/
\ No newline at end of file
diff --git a/airavata_mft/__init__.py b/airavata_mft/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/airavata_mft/asgi.py b/airavata_mft/asgi.py
new file mode 100644
index 0000000..876ad53
--- /dev/null
+++ b/airavata_mft/asgi.py
@@ -0,0 +1,16 @@
+"""
+ASGI config for airavata_mft_portal project.
+
+It exposes the ASGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/
+"""
+
+import os
+
+from django.core.asgi import get_asgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'airavata_mft.settings')
+
+application = get_asgi_application()
diff --git a/airavata_mft/settings.py b/airavata_mft/settings.py
new file mode 100644
index 0000000..bde9f31
--- /dev/null
+++ b/airavata_mft/settings.py
@@ -0,0 +1,125 @@
+"""
+Django settings for airavata_mft_portal project.
+
+Generated by 'django-admin startproject' using Django 3.0.3.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/3.0/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/3.0/ref/settings/
+"""
+
+import os
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = '2zw#dp!!b0)2xt_nhm=q)-*1174^g&uw6^bli)pmgbvbv=!ko4'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'rest_framework',
+    'apps.mft_agents'
+]
+
+MIDDLEWARE = [
+    'django.middleware.security.SecurityMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+]
+
+ROOT_URLCONF = 'airavata_mft.urls'
+
+TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        'DIRS': ['apps.mft_agents.templates', 'airavata_mft/templates'],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+            ],
+        },
+    },
+]
+
+WSGI_APPLICATION = 'airavata_mft.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.sqlite3',
+        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+    }
+}
+
+
+# Password validation
+# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+    },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/3.0/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/3.0/howto/static-files/
+
+STATICFILES_DIRS = [
+    os.path.join(BASE_DIR, "airavata_mft/static")
+]
+STATIC_URL = '/static/'
diff --git a/airavata_mft/static/base.css b/airavata_mft/static/base.css
new file mode 100644
index 0000000..2d60ece
--- /dev/null
+++ b/airavata_mft/static/base.css
@@ -0,0 +1,101 @@
+body {
+    font-size: .875rem;
+  }
+  
+  .feather {
+    width: 16px;
+    height: 16px;
+    vertical-align: text-bottom;
+  }
+  
+  /*
+   * Sidebar
+   */
+  
+  .sidebar {
+    position: fixed;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    z-index: 100; /* Behind the navbar */
+    padding: 48px 0 0; /* Height of navbar */
+    box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);
+  }
+  
+  .sidebar-sticky {
+    position: relative;
+    top: 0;
+    height: calc(100vh - 48px);
+    padding-top: .5rem;
+    overflow-x: hidden;
+    overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
+  }
+  
+  @supports ((position: -webkit-sticky) or (position: sticky)) {
+    .sidebar-sticky {
+      position: -webkit-sticky;
+      position: sticky;
+    }
+  }
+  
+  .sidebar .nav-link {
+    font-weight: 500;
+    color: #333;
+  }
+  
+  .sidebar .nav-link .feather {
+    margin-right: 4px;
+    color: #999;
+  }
+  
+  .sidebar .nav-link.active {
+    color: #007bff;
+  }
+  
+  .sidebar .nav-link:hover .feather,
+  .sidebar .nav-link.active .feather {
+    color: inherit;
+  }
+  
+  .sidebar-heading {
+    font-size: .75rem;
+    text-transform: uppercase;
+  }
+  
+  /*
+   * Content
+   */
+  
+  [role="main"] {
+    padding-top: 48px; /* Space for fixed navbar */
+  }
+  
+  /*
+   * Navbar
+   */
+  
+  .navbar-brand {
+    padding-top: .75rem;
+    padding-bottom: .75rem;
+    font-size: 1rem;
+    background-color: rgba(0, 0, 0, .25);
+    box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25);
+  }
+  
+  .navbar .form-control {
+    padding: .75rem 1rem;
+    border-width: 0;
+    border-radius: 0;
+  }
+  
+  .form-control-dark {
+    color: #fff;
+    background-color: rgba(255, 255, 255, .1);
+    border-color: rgba(255, 255, 255, .1);
+  }
+  
+  .form-control-dark:focus {
+    border-color: transparent;
+    box-shadow: 0 0 0 3px rgba(255, 255, 255, .25);
+  }
+  
\ No newline at end of file
diff --git a/airavata_mft/templates/base.html b/airavata_mft/templates/base.html
new file mode 100644
index 0000000..7d98897
--- /dev/null
+++ b/airavata_mft/templates/base.html
@@ -0,0 +1,89 @@
+{% load static %}
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta name="description" content="">
+    <meta name="author" content="">
+
+    <title>Airavata MFT</title>
+
+    <!--  Bootstrap CSS CDN -->
+    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
+
+    <!-- Custom styles -->
+    <link href="{% static 'base.css' %}" type="text/css" rel="stylesheet">
+  </head>
+
+  <body>
+    <nav class="navbar navbar-dark fixed-top bg-dark flex-md-nowrap p-0 shadow">
+      <a class="navbar-brand col-sm-3 col-md-2 mr-0" href="#">Airavata MFT</a>
+      <ul class="navbar-nav px-3">
+        <li class="nav-item text-nowrap">
+          <a class="nav-link" href="#">Sign out</a>
+        </li>
+      </ul>
+    </nav>
+
+    <div class="container-fluid">
+      <div class="row">
+        <nav class="col-md-2 d-none d-md-block bg-light sidebar">
+          <div class="sidebar-sticky">
+            <ul class="nav flex-column">
+              <li class="nav-item">
+                <a class="nav-link active" href="#">
+                  <span data-feather="home"></span>
+                  Agents <span class="sr-only">(current)</span>
+                </a>
+              </li>
+              <li class="nav-item">
+                <a class="nav-link" href="#">
+                  <span data-feather="file"></span>
+                  Transactions
+                </a>
+              </li>
+              <li class="nav-item">
+                <a class="nav-link" href="#">
+                  <span data-feather="shopping-cart"></span>
+                  Test
+                </a>
+              </li>
+              <li class="nav-item">
+                <a class="nav-link" href="#">
+                  <span data-feather="users"></span>
+                  Test
+                </a>
+              </li>
+              <li class="nav-item">
+                <a class="nav-link" href="#">
+                  <span data-feather="bar-chart-2"></span>
+                  Test
+                </a>
+              </li>
+              <li class="nav-item">
+                <a class="nav-link" href="#">
+                  <span data-feather="layers"></span>
+                  Test
+                </a>
+              </li>
+            </ul>
+          </div>
+        </nav>
+        
+        <main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-4">
+          <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
+            <h1 class="h2">{% block title %}Dashboard{% endblock title %}</h1>
+          </div>
+        </main>
+        {% block content %}
+        {% endblock content %}
+
+    <!-- Icons -->
+    <script src="https://unpkg.com/feather-icons/dist/feather.min.js"></script>
+    <script>
+      feather.replace()
+    </script>
+
+  </body>
+</html>
diff --git a/airavata_mft/urls.py b/airavata_mft/urls.py
new file mode 100644
index 0000000..e82bc1b
--- /dev/null
+++ b/airavata_mft/urls.py
@@ -0,0 +1,22 @@
+"""airavata_mft_portal URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+    https://docs.djangoproject.com/en/3.0/topics/http/urls/
+Examples:
+Function views
+    1. Add an import:  from my_app import views
+    2. Add a URL to urlpatterns:  path('', views.home, name='home')
+Class-based views
+    1. Add an import:  from other_app.views import Home
+    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
+Including another URLconf
+    1. Import the include() function: from django.urls import include, path
+    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
+"""
+from django.contrib import admin
+from django.urls import path, include
+
+urlpatterns = [
+    path('admin/', admin.site.urls),
+    path('agents/', include('apps.mft_agents.urls'))
+]
diff --git a/airavata_mft/wsgi.py b/airavata_mft/wsgi.py
new file mode 100644
index 0000000..8d235b2
--- /dev/null
+++ b/airavata_mft/wsgi.py
@@ -0,0 +1,16 @@
+"""
+WSGI config for airavata_mft_portal project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'airavata_mft.settings')
+
+application = get_wsgi_application()
diff --git a/apps/__init__.py b/apps/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/apps/mft_agents/__init__.py b/apps/mft_agents/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/apps/mft_agents/admin.py b/apps/mft_agents/admin.py
new file mode 100644
index 0000000..8c38f3f
--- /dev/null
+++ b/apps/mft_agents/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/apps/mft_agents/apps.py b/apps/mft_agents/apps.py
new file mode 100644
index 0000000..fa437f8
--- /dev/null
+++ b/apps/mft_agents/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class MftAgentsConfig(AppConfig):
+    name = 'mft_agents'
diff --git a/apps/mft_agents/migrations/__init__.py b/apps/mft_agents/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/apps/mft_agents/models.py b/apps/mft_agents/models.py
new file mode 100644
index 0000000..71a8362
--- /dev/null
+++ b/apps/mft_agents/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
diff --git a/apps/mft_agents/templates/mft_agents/agents_list.html b/apps/mft_agents/templates/mft_agents/agents_list.html
new file mode 100644
index 0000000..016cf81
--- /dev/null
+++ b/apps/mft_agents/templates/mft_agents/agents_list.html
@@ -0,0 +1,15 @@
+{% extends 'base.html' %}
+{% block title %}Browse Agents{% endblock title %}
+
+{% block content %}
+<div class="list-group col-md-9 ml-sm-auto col-lg-10 px-4">
+    {% for agent in agents.agents%}
+    <a href="/agent/{{agent.id}}" class="list-group-item list-group-item-action">
+      <div class="d-flex w-100 justify-content-between">
+        <h5 class="mb-1">{{agent.name}}</h5>
+      </div>
+      <p class="mb-1">{{agent.description}}</p>
+    </a>
+    {% endfor%}
+  </div>
+{% endblock content %}
diff --git a/apps/mft_agents/tests.py b/apps/mft_agents/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/apps/mft_agents/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/apps/mft_agents/urls.py b/apps/mft_agents/urls.py
new file mode 100644
index 0000000..476b4b4
--- /dev/null
+++ b/apps/mft_agents/urls.py
@@ -0,0 +1,5 @@
+from django.urls import path
+from . import views
+
+urlpatterns = [
+    path('', views.agents_list)]
diff --git a/apps/mft_agents/views.py b/apps/mft_agents/views.py
new file mode 100644
index 0000000..94c6676
--- /dev/null
+++ b/apps/mft_agents/views.py
@@ -0,0 +1,21 @@
+import logging
+from rest_framework.renderers import JSONRenderer
+from django.http import HttpResponse
+from django.template import loader
+
+
+logger = logging.getLogger(__name__)
+
+
+def agents_list(request):
+    # TODO: make request to MFT server here
+    agents_json = {"agents" :[{"id": "s3","name": "Amazon S3",
+  "description": "Amazon S3 or Amazon Simple Storage Service is a service offered by Amazon Web Services that provides object storage through a web service interface. Amazon S3 uses the same scalable storage infrastructure that Amazon.com uses to run its global e-commerce network."},
+   {"id": "box", "name": "Box",
+  "description": "With Box, you get a single place to manage, secure, share and govern all of the content for your internal and external collaboration and processes."}]}
+    template = loader.get_template('mft_agents/agents_list.html')
+    return HttpResponse(template.render({
+        'agents': agents_json
+    }, request))
+
+
diff --git a/gen_grpc_protos.ps1 b/gen_grpc_protos.ps1
new file mode 100644
index 0000000..3f6549b
--- /dev/null
+++ b/gen_grpc_protos.ps1
@@ -0,0 +1,9 @@
+# need git installed
+If(!(test-path .\googleapis)){
+    git clone https://github.com/googleapis/googleapis.git
+}
+cd googleapis
+git checkout f0b581b5bdf803e45201ecdb3688b60e381628a8
+cd ..
+$dest = ".\mft_backend\resource_service"
+python  -m grpc_tools.protoc -I .\googleapis -I .\..\airavata-mft\services\resource-service\stub\src\main\proto\ --python_out=$dest --grpc_python_out=$dest .\..\airavata-mft\services\resource-service\stub\src\main\proto\ResourceService.proto
diff --git a/gen_grpc_protos.sh b/gen_grpc_protos.sh
new file mode 100644
index 0000000..c301f35
--- /dev/null
+++ b/gen_grpc_protos.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# need git installed
+if test ! -d "./googleapis"
+then
+    git clone https://github.com/googleapis/googleapis.git
+fi
+
+cd googleapis
+git checkout f0b581b5bdf803e45201ecdb3688b60e381628a8
+cd ..
+dest="./mft_backend/resource_service"
+python  -m grpc_tools.protoc -I ./googleapis -I ./../airavata-mft/services/resource-service/stub/src/main/proto/ --python_out=$dest --grpc_python_out=$dest ./../airavata-mft/services/resource-service/stub/src/main/proto/ResourceService.proto
diff --git a/manage.py b/manage.py
new file mode 100644
index 0000000..416465c
--- /dev/null
+++ b/manage.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'airavata_mft.settings')
+    try:
+        from django.core.management import execute_from_command_line
+    except ImportError as exc:
+        try:
+            import django
+        except ImportError:
+            raise ImportError(
+                "Couldn't import Django. Are you sure it's installed and "
+                "available on your PYTHONPATH environment variable? Did you "
+                "forget to activate a virtual environment?"
+            ) from exc
+    execute_from_command_line(sys.argv)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/mft_backend/__init__.py b/mft_backend/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/mft_backend/resource_service/ClientStub.py b/mft_backend/resource_service/ClientStub.py
new file mode 100644
index 0000000..c0e58bd
--- /dev/null
+++ b/mft_backend/resource_service/ClientStub.py
@@ -0,0 +1,61 @@
+import grpc
+import sys
+import mft_backend.resource_service.ResourceService_pb2 as ResourceService_pb2
+import mft_backend.resource_service.ResourceService_pb2_grpc as ResourceService_pb2_grpc
+
+
+class ResourceServiceClient(object):
+
+    def __init__(self):
+        self.stub = self._connect_to_resource_server()
+
+    @staticmethod
+    def _connect_to_resource_server():
+        # TODO: once TLS is enabled in server change this
+        channel = grpc.insecure_channel('localhost:9093')
+        try:
+            grpc.channel_ready_future(channel).result(timeout=10)
+        except grpc.FutureTimeoutError:
+            sys.exit('Error connecting to server')
+        else:
+            stub = ResourceService_pb2_grpc.ResourceServiceStub(channel)
+            return stub
+
+    def get_scp_storage(self, request):
+        rpc_request = ResourceService_pb2.SCPStorageGetRequest(storageId=request.storage_id)
+        return self.stub.getSCPStorage(rpc_request)
+
+    def create_scp_storage(self, request):
+        rpc_request = ResourceService_pb2.SCPStorageCreateRequest(host=request.host, port=request.port)
+        return self.stub.createSCPStorage(rpc_request)
+
+    def update_scp_storage(self, request):
+        rpc_request = ResourceService_pb2.SCPStorageUpdateRequest(storageId=request.storage_id, host=request.host, port=request.port)
+        return self.stub.updateSCPStorage(rpc_request)
+
+    def delete_scp_storage(self, request):
+        rpc_request = ResourceService_pb2.SCPStorageDeleteRequest(storageId=request.storage_id)
+        return self.stub.deleteSCPStorage(rpc_request)
+
+    def get_scp_resource(self, request):
+        rpc_request = ResourceService_pb2.SCPResourceGetRequest(resourceId=request.resource_id)
+        return self.stub.getSCPResource(rpc_request)
+
+    def create_scp_resource(self, request):
+        rpc_request = ResourceService_pb2.SCPResourceCreateRequest(scpStorageId=request.scp_storage_id, resourcePath=request.resource_path)
+        return self.stub.createSCPStorage(rpc_request)
+
+    def update_scp_resource(self, request):
+        rpc_request = ResourceService_pb2.SCPResourceUpdateRequest(scpStorageId=request.scp_storage_id,
+                                                                   resourcePath=request.resource_path,
+                                                                   resourceId=request.request_id)
+        return self.stub.updateSCPResource(rpc_request)
+
+    def delete_scp_resource(self, request):
+        rpc_request = ResourceService_pb2.SCPResourceDeleteRequest(resourceId=request.request_id)
+        return self.stub.deleteSCPResource(rpc_request)
+
+# for testing
+# if __name__ == "__main__":
+#     client = ResourceServiceClient()
+#     client.get_scp_storage("test")
\ No newline at end of file
diff --git a/mft_backend/resource_service/ResourceService_pb2.py b/mft_backend/resource_service/ResourceService_pb2.py
new file mode 100644
index 0000000..2f63c9e
--- /dev/null
+++ b/mft_backend/resource_service/ResourceService_pb2.py
@@ -0,0 +1,826 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: ResourceService.proto
+
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='ResourceService.proto',
+  package='org.apache.airavata.mft.resource.service',
+  syntax='proto3',
+  serialized_options=b'P\001',
+  serialized_pb=b'\n\x15ResourceService.proto\x12(org.apache.airavata.mft.resource.service\x1a\x1cgoogle/api/annotations.proto\x1a\x1bgoogle/protobuf/empty.proto\";\n\nSCPStorage\x12\x11\n\tstorageId\x18\x01 \x01(\t\x12\x0c\n\x04host\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\x05\")\n\x14SCPStorageGetRequest\x12\x11\n\tstorageId\x18\x01 \x01(\t\"5\n\x17SCPStorageCreateRequest\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\x05\"H\n\x17SCPStorageUpdateRequest\x12\x1 [...]
+  ,
+  dependencies=[google_dot_api_dot_annotations__pb2.DESCRIPTOR,google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,])
+
+
+
+
+_SCPSTORAGE = _descriptor.Descriptor(
+  name='SCPStorage',
+  full_name='org.apache.airavata.mft.resource.service.SCPStorage',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='storageId', full_name='org.apache.airavata.mft.resource.service.SCPStorage.storageId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='host', full_name='org.apache.airavata.mft.resource.service.SCPStorage.host', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='port', full_name='org.apache.airavata.mft.resource.service.SCPStorage.port', index=2,
+      number=3, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=126,
+  serialized_end=185,
+)
+
+
+_SCPSTORAGEGETREQUEST = _descriptor.Descriptor(
+  name='SCPStorageGetRequest',
+  full_name='org.apache.airavata.mft.resource.service.SCPStorageGetRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='storageId', full_name='org.apache.airavata.mft.resource.service.SCPStorageGetRequest.storageId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=187,
+  serialized_end=228,
+)
+
+
+_SCPSTORAGECREATEREQUEST = _descriptor.Descriptor(
+  name='SCPStorageCreateRequest',
+  full_name='org.apache.airavata.mft.resource.service.SCPStorageCreateRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='host', full_name='org.apache.airavata.mft.resource.service.SCPStorageCreateRequest.host', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='port', full_name='org.apache.airavata.mft.resource.service.SCPStorageCreateRequest.port', index=1,
+      number=2, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=230,
+  serialized_end=283,
+)
+
+
+_SCPSTORAGEUPDATEREQUEST = _descriptor.Descriptor(
+  name='SCPStorageUpdateRequest',
+  full_name='org.apache.airavata.mft.resource.service.SCPStorageUpdateRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='storageId', full_name='org.apache.airavata.mft.resource.service.SCPStorageUpdateRequest.storageId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='host', full_name='org.apache.airavata.mft.resource.service.SCPStorageUpdateRequest.host', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='port', full_name='org.apache.airavata.mft.resource.service.SCPStorageUpdateRequest.port', index=2,
+      number=3, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=285,
+  serialized_end=357,
+)
+
+
+_SCPSTORAGEDELETEREQUEST = _descriptor.Descriptor(
+  name='SCPStorageDeleteRequest',
+  full_name='org.apache.airavata.mft.resource.service.SCPStorageDeleteRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='storageId', full_name='org.apache.airavata.mft.resource.service.SCPStorageDeleteRequest.storageId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=359,
+  serialized_end=403,
+)
+
+
+_SCPRESOURCE = _descriptor.Descriptor(
+  name='SCPResource',
+  full_name='org.apache.airavata.mft.resource.service.SCPResource',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='resourceId', full_name='org.apache.airavata.mft.resource.service.SCPResource.resourceId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='scpStorage', full_name='org.apache.airavata.mft.resource.service.SCPResource.scpStorage', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='resourcePath', full_name='org.apache.airavata.mft.resource.service.SCPResource.resourcePath', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=406,
+  serialized_end=535,
+)
+
+
+_SCPRESOURCEGETREQUEST = _descriptor.Descriptor(
+  name='SCPResourceGetRequest',
+  full_name='org.apache.airavata.mft.resource.service.SCPResourceGetRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='resourceId', full_name='org.apache.airavata.mft.resource.service.SCPResourceGetRequest.resourceId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=537,
+  serialized_end=580,
+)
+
+
+_SCPRESOURCECREATEREQUEST = _descriptor.Descriptor(
+  name='SCPResourceCreateRequest',
+  full_name='org.apache.airavata.mft.resource.service.SCPResourceCreateRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='scpStorageId', full_name='org.apache.airavata.mft.resource.service.SCPResourceCreateRequest.scpStorageId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='resourcePath', full_name='org.apache.airavata.mft.resource.service.SCPResourceCreateRequest.resourcePath', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=582,
+  serialized_end=652,
+)
+
+
+_SCPRESOURCEUPDATEREQUEST = _descriptor.Descriptor(
+  name='SCPResourceUpdateRequest',
+  full_name='org.apache.airavata.mft.resource.service.SCPResourceUpdateRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='resourceId', full_name='org.apache.airavata.mft.resource.service.SCPResourceUpdateRequest.resourceId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='scpStorageId', full_name='org.apache.airavata.mft.resource.service.SCPResourceUpdateRequest.scpStorageId', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='resourcePath', full_name='org.apache.airavata.mft.resource.service.SCPResourceUpdateRequest.resourcePath', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=654,
+  serialized_end=744,
+)
+
+
+_SCPRESOURCEDELETEREQUEST = _descriptor.Descriptor(
+  name='SCPResourceDeleteRequest',
+  full_name='org.apache.airavata.mft.resource.service.SCPResourceDeleteRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='resourceId', full_name='org.apache.airavata.mft.resource.service.SCPResourceDeleteRequest.resourceId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=746,
+  serialized_end=792,
+)
+
+
+_LOCALRESOURCE = _descriptor.Descriptor(
+  name='LocalResource',
+  full_name='org.apache.airavata.mft.resource.service.LocalResource',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='resourceId', full_name='org.apache.airavata.mft.resource.service.LocalResource.resourceId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='resourcePath', full_name='org.apache.airavata.mft.resource.service.LocalResource.resourcePath', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=794,
+  serialized_end=851,
+)
+
+
+_LOCALRESOURCEGETREQUEST = _descriptor.Descriptor(
+  name='LocalResourceGetRequest',
+  full_name='org.apache.airavata.mft.resource.service.LocalResourceGetRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='resourceId', full_name='org.apache.airavata.mft.resource.service.LocalResourceGetRequest.resourceId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=853,
+  serialized_end=898,
+)
+
+
+_LOCALRESOURCECREATEREQUEST = _descriptor.Descriptor(
+  name='LocalResourceCreateRequest',
+  full_name='org.apache.airavata.mft.resource.service.LocalResourceCreateRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='resourcePath', full_name='org.apache.airavata.mft.resource.service.LocalResourceCreateRequest.resourcePath', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=900,
+  serialized_end=950,
+)
+
+
+_LOCALRESOURCEUPDATEREQUEST = _descriptor.Descriptor(
+  name='LocalResourceUpdateRequest',
+  full_name='org.apache.airavata.mft.resource.service.LocalResourceUpdateRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='resourceId', full_name='org.apache.airavata.mft.resource.service.LocalResourceUpdateRequest.resourceId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='resourcePath', full_name='org.apache.airavata.mft.resource.service.LocalResourceUpdateRequest.resourcePath', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=952,
+  serialized_end=1022,
+)
+
+
+_LOCALRESOURCEDELETEREQUEST = _descriptor.Descriptor(
+  name='LocalResourceDeleteRequest',
+  full_name='org.apache.airavata.mft.resource.service.LocalResourceDeleteRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='resourceId', full_name='org.apache.airavata.mft.resource.service.LocalResourceDeleteRequest.resourceId', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1024,
+  serialized_end=1072,
+)
+
+_SCPRESOURCE.fields_by_name['scpStorage'].message_type = _SCPSTORAGE
+DESCRIPTOR.message_types_by_name['SCPStorage'] = _SCPSTORAGE
+DESCRIPTOR.message_types_by_name['SCPStorageGetRequest'] = _SCPSTORAGEGETREQUEST
+DESCRIPTOR.message_types_by_name['SCPStorageCreateRequest'] = _SCPSTORAGECREATEREQUEST
+DESCRIPTOR.message_types_by_name['SCPStorageUpdateRequest'] = _SCPSTORAGEUPDATEREQUEST
+DESCRIPTOR.message_types_by_name['SCPStorageDeleteRequest'] = _SCPSTORAGEDELETEREQUEST
+DESCRIPTOR.message_types_by_name['SCPResource'] = _SCPRESOURCE
+DESCRIPTOR.message_types_by_name['SCPResourceGetRequest'] = _SCPRESOURCEGETREQUEST
+DESCRIPTOR.message_types_by_name['SCPResourceCreateRequest'] = _SCPRESOURCECREATEREQUEST
+DESCRIPTOR.message_types_by_name['SCPResourceUpdateRequest'] = _SCPRESOURCEUPDATEREQUEST
+DESCRIPTOR.message_types_by_name['SCPResourceDeleteRequest'] = _SCPRESOURCEDELETEREQUEST
+DESCRIPTOR.message_types_by_name['LocalResource'] = _LOCALRESOURCE
+DESCRIPTOR.message_types_by_name['LocalResourceGetRequest'] = _LOCALRESOURCEGETREQUEST
+DESCRIPTOR.message_types_by_name['LocalResourceCreateRequest'] = _LOCALRESOURCECREATEREQUEST
+DESCRIPTOR.message_types_by_name['LocalResourceUpdateRequest'] = _LOCALRESOURCEUPDATEREQUEST
+DESCRIPTOR.message_types_by_name['LocalResourceDeleteRequest'] = _LOCALRESOURCEDELETEREQUEST
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+SCPStorage = _reflection.GeneratedProtocolMessageType('SCPStorage', (_message.Message,), {
+  'DESCRIPTOR' : _SCPSTORAGE,
+  '__module__' : 'ResourceService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.airavata.mft.resource.service.SCPStorage)
+  })
+_sym_db.RegisterMessage(SCPStorage)
+
+SCPStorageGetRequest = _reflection.GeneratedProtocolMessageType('SCPStorageGetRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SCPSTORAGEGETREQUEST,
+  '__module__' : 'ResourceService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.airavata.mft.resource.service.SCPStorageGetRequest)
+  })
+_sym_db.RegisterMessage(SCPStorageGetRequest)
+
+SCPStorageCreateRequest = _reflection.GeneratedProtocolMessageType('SCPStorageCreateRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SCPSTORAGECREATEREQUEST,
+  '__module__' : 'ResourceService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.airavata.mft.resource.service.SCPStorageCreateRequest)
+  })
+_sym_db.RegisterMessage(SCPStorageCreateRequest)
+
+SCPStorageUpdateRequest = _reflection.GeneratedProtocolMessageType('SCPStorageUpdateRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SCPSTORAGEUPDATEREQUEST,
+  '__module__' : 'ResourceService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.airavata.mft.resource.service.SCPStorageUpdateRequest)
+  })
+_sym_db.RegisterMessage(SCPStorageUpdateRequest)
+
+SCPStorageDeleteRequest = _reflection.GeneratedProtocolMessageType('SCPStorageDeleteRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SCPSTORAGEDELETEREQUEST,
+  '__module__' : 'ResourceService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.airavata.mft.resource.service.SCPStorageDeleteRequest)
+  })
+_sym_db.RegisterMessage(SCPStorageDeleteRequest)
+
+SCPResource = _reflection.GeneratedProtocolMessageType('SCPResource', (_message.Message,), {
+  'DESCRIPTOR' : _SCPRESOURCE,
+  '__module__' : 'ResourceService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.airavata.mft.resource.service.SCPResource)
+  })
+_sym_db.RegisterMessage(SCPResource)
+
+SCPResourceGetRequest = _reflection.GeneratedProtocolMessageType('SCPResourceGetRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SCPRESOURCEGETREQUEST,
+  '__module__' : 'ResourceService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.airavata.mft.resource.service.SCPResourceGetRequest)
+  })
+_sym_db.RegisterMessage(SCPResourceGetRequest)
+
+SCPResourceCreateRequest = _reflection.GeneratedProtocolMessageType('SCPResourceCreateRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SCPRESOURCECREATEREQUEST,
+  '__module__' : 'ResourceService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.airavata.mft.resource.service.SCPResourceCreateRequest)
+  })
+_sym_db.RegisterMessage(SCPResourceCreateRequest)
+
+SCPResourceUpdateRequest = _reflection.GeneratedProtocolMessageType('SCPResourceUpdateRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SCPRESOURCEUPDATEREQUEST,
+  '__module__' : 'ResourceService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.airavata.mft.resource.service.SCPResourceUpdateRequest)
+  })
+_sym_db.RegisterMessage(SCPResourceUpdateRequest)
+
+SCPResourceDeleteRequest = _reflection.GeneratedProtocolMessageType('SCPResourceDeleteRequest', (_message.Message,), {
+  'DESCRIPTOR' : _SCPRESOURCEDELETEREQUEST,
+  '__module__' : 'ResourceService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.airavata.mft.resource.service.SCPResourceDeleteRequest)
+  })
+_sym_db.RegisterMessage(SCPResourceDeleteRequest)
+
+LocalResource = _reflection.GeneratedProtocolMessageType('LocalResource', (_message.Message,), {
+  'DESCRIPTOR' : _LOCALRESOURCE,
+  '__module__' : 'ResourceService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.airavata.mft.resource.service.LocalResource)
+  })
+_sym_db.RegisterMessage(LocalResource)
+
+LocalResourceGetRequest = _reflection.GeneratedProtocolMessageType('LocalResourceGetRequest', (_message.Message,), {
+  'DESCRIPTOR' : _LOCALRESOURCEGETREQUEST,
+  '__module__' : 'ResourceService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.airavata.mft.resource.service.LocalResourceGetRequest)
+  })
+_sym_db.RegisterMessage(LocalResourceGetRequest)
+
+LocalResourceCreateRequest = _reflection.GeneratedProtocolMessageType('LocalResourceCreateRequest', (_message.Message,), {
+  'DESCRIPTOR' : _LOCALRESOURCECREATEREQUEST,
+  '__module__' : 'ResourceService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.airavata.mft.resource.service.LocalResourceCreateRequest)
+  })
+_sym_db.RegisterMessage(LocalResourceCreateRequest)
+
+LocalResourceUpdateRequest = _reflection.GeneratedProtocolMessageType('LocalResourceUpdateRequest', (_message.Message,), {
+  'DESCRIPTOR' : _LOCALRESOURCEUPDATEREQUEST,
+  '__module__' : 'ResourceService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.airavata.mft.resource.service.LocalResourceUpdateRequest)
+  })
+_sym_db.RegisterMessage(LocalResourceUpdateRequest)
+
+LocalResourceDeleteRequest = _reflection.GeneratedProtocolMessageType('LocalResourceDeleteRequest', (_message.Message,), {
+  'DESCRIPTOR' : _LOCALRESOURCEDELETEREQUEST,
+  '__module__' : 'ResourceService_pb2'
+  # @@protoc_insertion_point(class_scope:org.apache.airavata.mft.resource.service.LocalResourceDeleteRequest)
+  })
+_sym_db.RegisterMessage(LocalResourceDeleteRequest)
+
+
+DESCRIPTOR._options = None
+
+_RESOURCESERVICE = _descriptor.ServiceDescriptor(
+  name='ResourceService',
+  full_name='org.apache.airavata.mft.resource.service.ResourceService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  serialized_start=1075,
+  serialized_end=3014,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='getSCPStorage',
+    full_name='org.apache.airavata.mft.resource.service.ResourceService.getSCPStorage',
+    index=0,
+    containing_service=None,
+    input_type=_SCPSTORAGEGETREQUEST,
+    output_type=_SCPSTORAGE,
+    serialized_options=b'\202\323\344\223\002\034\022\032/v1.0/resource/scp/storage',
+  ),
+  _descriptor.MethodDescriptor(
+    name='createSCPStorage',
+    full_name='org.apache.airavata.mft.resource.service.ResourceService.createSCPStorage',
+    index=1,
+    containing_service=None,
+    input_type=_SCPSTORAGECREATEREQUEST,
+    output_type=_SCPSTORAGE,
+    serialized_options=b'\202\323\344\223\002\034\"\032/v1.0/resource/scp/storage',
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateSCPStorage',
+    full_name='org.apache.airavata.mft.resource.service.ResourceService.updateSCPStorage',
+    index=2,
+    containing_service=None,
+    input_type=_SCPSTORAGEUPDATEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=b'\202\323\344\223\002\034\032\032/v1.0/resource/scp/storage',
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteSCPStorage',
+    full_name='org.apache.airavata.mft.resource.service.ResourceService.deleteSCPStorage',
+    index=3,
+    containing_service=None,
+    input_type=_SCPSTORAGEDELETEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=b'\202\323\344\223\002\034*\032/v1.0/resource/scp/storage',
+  ),
+  _descriptor.MethodDescriptor(
+    name='getSCPResource',
+    full_name='org.apache.airavata.mft.resource.service.ResourceService.getSCPResource',
+    index=4,
+    containing_service=None,
+    input_type=_SCPRESOURCEGETREQUEST,
+    output_type=_SCPRESOURCE,
+    serialized_options=b'\202\323\344\223\002\024\022\022/v1.0/resource/scp',
+  ),
+  _descriptor.MethodDescriptor(
+    name='createSCPResource',
+    full_name='org.apache.airavata.mft.resource.service.ResourceService.createSCPResource',
+    index=5,
+    containing_service=None,
+    input_type=_SCPRESOURCECREATEREQUEST,
+    output_type=_SCPRESOURCE,
+    serialized_options=b'\202\323\344\223\002\024\"\022/v1.0/resource/scp',
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateSCPResource',
+    full_name='org.apache.airavata.mft.resource.service.ResourceService.updateSCPResource',
+    index=6,
+    containing_service=None,
+    input_type=_SCPRESOURCEUPDATEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=b'\202\323\344\223\002\024\032\022/v1.0/resource/scp',
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteSCPResource',
+    full_name='org.apache.airavata.mft.resource.service.ResourceService.deleteSCPResource',
+    index=7,
+    containing_service=None,
+    input_type=_SCPRESOURCEDELETEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=b'\202\323\344\223\002\024*\022/v1.0/resource/scp',
+  ),
+  _descriptor.MethodDescriptor(
+    name='getLocalResource',
+    full_name='org.apache.airavata.mft.resource.service.ResourceService.getLocalResource',
+    index=8,
+    containing_service=None,
+    input_type=_LOCALRESOURCEGETREQUEST,
+    output_type=_LOCALRESOURCE,
+    serialized_options=b'\202\323\344\223\002\026\022\024/v1.0/resource/local',
+  ),
+  _descriptor.MethodDescriptor(
+    name='createLocalResource',
+    full_name='org.apache.airavata.mft.resource.service.ResourceService.createLocalResource',
+    index=9,
+    containing_service=None,
+    input_type=_LOCALRESOURCECREATEREQUEST,
+    output_type=_LOCALRESOURCE,
+    serialized_options=b'\202\323\344\223\002\026\"\024/v1.0/resource/local',
+  ),
+  _descriptor.MethodDescriptor(
+    name='updateLocalResource',
+    full_name='org.apache.airavata.mft.resource.service.ResourceService.updateLocalResource',
+    index=10,
+    containing_service=None,
+    input_type=_LOCALRESOURCEUPDATEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=b'\202\323\344\223\002\026\032\024/v1.0/resource/local',
+  ),
+  _descriptor.MethodDescriptor(
+    name='deleteLocalResource',
+    full_name='org.apache.airavata.mft.resource.service.ResourceService.deleteLocalResource',
+    index=11,
+    containing_service=None,
+    input_type=_LOCALRESOURCEDELETEREQUEST,
+    output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
+    serialized_options=b'\202\323\344\223\002\026*\024/v1.0/resource/local',
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_RESOURCESERVICE)
+
+DESCRIPTOR.services_by_name['ResourceService'] = _RESOURCESERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/mft_backend/resource_service/ResourceService_pb2_grpc.py b/mft_backend/resource_service/ResourceService_pb2_grpc.py
new file mode 100644
index 0000000..43704f2
--- /dev/null
+++ b/mft_backend/resource_service/ResourceService_pb2_grpc.py
@@ -0,0 +1,236 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+import grpc
+
+import mft_backend.resource_service.ResourceService_pb2 as ResourceService__pb2
+from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+
+
+class ResourceServiceStub(object):
+  """SCP Storage
+  """
+
+  def __init__(self, channel):
+    """Constructor.
+
+    Args:
+      channel: A grpc.Channel.
+    """
+    self.getSCPStorage = channel.unary_unary(
+        '/org.apache.airavata.mft.resource.service.ResourceService/getSCPStorage',
+        request_serializer=ResourceService__pb2.SCPStorageGetRequest.SerializeToString,
+        response_deserializer=ResourceService__pb2.SCPStorage.FromString,
+        )
+    self.createSCPStorage = channel.unary_unary(
+        '/org.apache.airavata.mft.resource.service.ResourceService/createSCPStorage',
+        request_serializer=ResourceService__pb2.SCPStorageCreateRequest.SerializeToString,
+        response_deserializer=ResourceService__pb2.SCPStorage.FromString,
+        )
+    self.updateSCPStorage = channel.unary_unary(
+        '/org.apache.airavata.mft.resource.service.ResourceService/updateSCPStorage',
+        request_serializer=ResourceService__pb2.SCPStorageUpdateRequest.SerializeToString,
+        response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+        )
+    self.deleteSCPStorage = channel.unary_unary(
+        '/org.apache.airavata.mft.resource.service.ResourceService/deleteSCPStorage',
+        request_serializer=ResourceService__pb2.SCPStorageDeleteRequest.SerializeToString,
+        response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+        )
+    self.getSCPResource = channel.unary_unary(
+        '/org.apache.airavata.mft.resource.service.ResourceService/getSCPResource',
+        request_serializer=ResourceService__pb2.SCPResourceGetRequest.SerializeToString,
+        response_deserializer=ResourceService__pb2.SCPResource.FromString,
+        )
+    self.createSCPResource = channel.unary_unary(
+        '/org.apache.airavata.mft.resource.service.ResourceService/createSCPResource',
+        request_serializer=ResourceService__pb2.SCPResourceCreateRequest.SerializeToString,
+        response_deserializer=ResourceService__pb2.SCPResource.FromString,
+        )
+    self.updateSCPResource = channel.unary_unary(
+        '/org.apache.airavata.mft.resource.service.ResourceService/updateSCPResource',
+        request_serializer=ResourceService__pb2.SCPResourceUpdateRequest.SerializeToString,
+        response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+        )
+    self.deleteSCPResource = channel.unary_unary(
+        '/org.apache.airavata.mft.resource.service.ResourceService/deleteSCPResource',
+        request_serializer=ResourceService__pb2.SCPResourceDeleteRequest.SerializeToString,
+        response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+        )
+    self.getLocalResource = channel.unary_unary(
+        '/org.apache.airavata.mft.resource.service.ResourceService/getLocalResource',
+        request_serializer=ResourceService__pb2.LocalResourceGetRequest.SerializeToString,
+        response_deserializer=ResourceService__pb2.LocalResource.FromString,
+        )
+    self.createLocalResource = channel.unary_unary(
+        '/org.apache.airavata.mft.resource.service.ResourceService/createLocalResource',
+        request_serializer=ResourceService__pb2.LocalResourceCreateRequest.SerializeToString,
+        response_deserializer=ResourceService__pb2.LocalResource.FromString,
+        )
+    self.updateLocalResource = channel.unary_unary(
+        '/org.apache.airavata.mft.resource.service.ResourceService/updateLocalResource',
+        request_serializer=ResourceService__pb2.LocalResourceUpdateRequest.SerializeToString,
+        response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+        )
+    self.deleteLocalResource = channel.unary_unary(
+        '/org.apache.airavata.mft.resource.service.ResourceService/deleteLocalResource',
+        request_serializer=ResourceService__pb2.LocalResourceDeleteRequest.SerializeToString,
+        response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
+        )
+
+
+class ResourceServiceServicer(object):
+  """SCP Storage
+  """
+
+  def getSCPStorage(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def createSCPStorage(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def updateSCPStorage(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def deleteSCPStorage(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getSCPResource(self, request, context):
+    """SCP Resource
+
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def createSCPResource(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def updateSCPResource(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def deleteSCPResource(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def getLocalResource(self, request, context):
+    """Local Resource
+
+    """
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def createLocalResource(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def updateLocalResource(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+  def deleteLocalResource(self, request, context):
+    # missing associated documentation comment in .proto file
+    pass
+    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+    context.set_details('Method not implemented!')
+    raise NotImplementedError('Method not implemented!')
+
+
+def add_ResourceServiceServicer_to_server(servicer, server):
+  rpc_method_handlers = {
+      'getSCPStorage': grpc.unary_unary_rpc_method_handler(
+          servicer.getSCPStorage,
+          request_deserializer=ResourceService__pb2.SCPStorageGetRequest.FromString,
+          response_serializer=ResourceService__pb2.SCPStorage.SerializeToString,
+      ),
+      'createSCPStorage': grpc.unary_unary_rpc_method_handler(
+          servicer.createSCPStorage,
+          request_deserializer=ResourceService__pb2.SCPStorageCreateRequest.FromString,
+          response_serializer=ResourceService__pb2.SCPStorage.SerializeToString,
+      ),
+      'updateSCPStorage': grpc.unary_unary_rpc_method_handler(
+          servicer.updateSCPStorage,
+          request_deserializer=ResourceService__pb2.SCPStorageUpdateRequest.FromString,
+          response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+      ),
+      'deleteSCPStorage': grpc.unary_unary_rpc_method_handler(
+          servicer.deleteSCPStorage,
+          request_deserializer=ResourceService__pb2.SCPStorageDeleteRequest.FromString,
+          response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+      ),
+      'getSCPResource': grpc.unary_unary_rpc_method_handler(
+          servicer.getSCPResource,
+          request_deserializer=ResourceService__pb2.SCPResourceGetRequest.FromString,
+          response_serializer=ResourceService__pb2.SCPResource.SerializeToString,
+      ),
+      'createSCPResource': grpc.unary_unary_rpc_method_handler(
+          servicer.createSCPResource,
+          request_deserializer=ResourceService__pb2.SCPResourceCreateRequest.FromString,
+          response_serializer=ResourceService__pb2.SCPResource.SerializeToString,
+      ),
+      'updateSCPResource': grpc.unary_unary_rpc_method_handler(
+          servicer.updateSCPResource,
+          request_deserializer=ResourceService__pb2.SCPResourceUpdateRequest.FromString,
+          response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+      ),
+      'deleteSCPResource': grpc.unary_unary_rpc_method_handler(
+          servicer.deleteSCPResource,
+          request_deserializer=ResourceService__pb2.SCPResourceDeleteRequest.FromString,
+          response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+      ),
+      'getLocalResource': grpc.unary_unary_rpc_method_handler(
+          servicer.getLocalResource,
+          request_deserializer=ResourceService__pb2.LocalResourceGetRequest.FromString,
+          response_serializer=ResourceService__pb2.LocalResource.SerializeToString,
+      ),
+      'createLocalResource': grpc.unary_unary_rpc_method_handler(
+          servicer.createLocalResource,
+          request_deserializer=ResourceService__pb2.LocalResourceCreateRequest.FromString,
+          response_serializer=ResourceService__pb2.LocalResource.SerializeToString,
+      ),
+      'updateLocalResource': grpc.unary_unary_rpc_method_handler(
+          servicer.updateLocalResource,
+          request_deserializer=ResourceService__pb2.LocalResourceUpdateRequest.FromString,
+          response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+      ),
+      'deleteLocalResource': grpc.unary_unary_rpc_method_handler(
+          servicer.deleteLocalResource,
+          request_deserializer=ResourceService__pb2.LocalResourceDeleteRequest.FromString,
+          response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
+      ),
+  }
+  generic_handler = grpc.method_handlers_generic_handler(
+      'org.apache.airavata.mft.resource.service.ResourceService', rpc_method_handlers)
+  server.add_generic_rpc_handlers((generic_handler,))
diff --git a/mft_backend/resource_service/__init__.py b/mft_backend/resource_service/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..11fef13
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,4 @@
+Django==3.0.4
+djangorestframework==3.11.0
+grpcio==1.27.2
+googleapis-common-protos==1.51.0