airavata-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From machris...@apache.org
Subject [airavata-django-portal] 02/07: Refactored Thrift client utility code for reusability
Date Sat, 21 Jul 2018 20:12:56 GMT
This is an automated email from the ASF dual-hosted git repository.

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

commit ee16f0b1ce11268de83ace5a468e3bd95b8d80df
Author: Marcus Christie <machrist@iu.edu>
AuthorDate: Fri Jul 20 13:42:02 2018 -0400

    Refactored Thrift client utility code for reusability
---
 django_airavata/middleware.py | 174 ++++++++---------------------------------
 django_airavata/utils.py      | 175 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 205 insertions(+), 144 deletions(-)

diff --git a/django_airavata/middleware.py b/django_airavata/middleware.py
index f407864..5e82e7f 100644
--- a/django_airavata/middleware.py
+++ b/django_airavata/middleware.py
@@ -1,95 +1,9 @@
 
-from airavata.api import Airavata
-from airavata.api.sharing import SharingRegistryService
-from airavata.service.profile.groupmanager.cpi.constants \
-    import GROUP_MANAGER_CPI_NAME
-from airavata.service.profile.groupmanager.cpi import GroupManagerService
-from airavata.service.profile.iam.admin.services.cpi.constants \
-    import IAM_ADMIN_SERVICES_CPI_NAME
-from airavata.service.profile.iam.admin.services.cpi import IamAdminServices
-from airavata.service.profile.tenant.cpi.constants \
-    import TENANT_PROFILE_CPI_NAME
-from airavata.service.profile.tenant.cpi import TenantProfileService
-from airavata.service.profile.user.cpi.constants \
-    import USER_PROFILE_CPI_NAME
-from airavata.service.profile.user.cpi import UserProfileService
-
-from thrift import Thrift
-from thrift.transport import TSSLSocket
-from thrift.transport import TSocket
-from thrift.transport import TTransport
-from thrift.protocol import TBinaryProtocol
-from thrift.protocol.TMultiplexedProtocol import TMultiplexedProtocol
-
-from django.conf import settings
-
 import logging
 
-logger = logging.getLogger(__name__)
-
-def get_unsecure_transport(hostname, port):
-    # Create a socket to the Airavata Server
-    transport = TSocket.TSocket(hostname, port)
-
-    # Use Buffered Protocol to speedup over raw sockets
-    transport = TTransport.TBufferedTransport(transport)
-    return transport
-
-def get_secure_transport(hostname, port):
-
-    # Create a socket to the Airavata Server
-    # TODO: validate server certificate
-    transport = TSSLSocket.TSSLSocket(hostname, port, validate=False)
-
-    # Use Buffered Protocol to speedup over raw sockets
-    transport = TTransport.TBufferedTransport(transport)
-    return transport
-
-def get_transport(hostname, port, secure=True):
-    if secure:
-        transport = get_secure_transport(hostname, port)
-    else:
-        transport = get_unsecure_transport(hostname, port)
-    return transport
-
-def get_airavata_client(transport):
-
-    # Airavata currently uses Binary Protocol
-    protocol = TBinaryProtocol.TBinaryProtocol(transport)
-
-    # Create a Airavata client to use the protocol encoder
-    client=Airavata.Client(protocol)
-    return client
-
-def get_sharing_client(transport):
-
-    protocol = TBinaryProtocol.TBinaryProtocol(transport)
-
-    return SharingRegistryService.Client(protocol)
-
-
-def get_binary_protocol(transport):
-    return TBinaryProtocol.TBinaryProtocol(transport)
-
-
-def get_group_manager_client(protocol):
-    multiplex_prot = TMultiplexedProtocol(protocol, GROUP_MANAGER_CPI_NAME)
-    return GroupManagerService.Client(multiplex_prot)
-
-
-def get_iamadmin_client(protocol):
-    multiplex_prot = TMultiplexedProtocol(protocol, IAM_ADMIN_SERVICES_CPI_NAME)
-    return IamAdminServices.Client(multiplex_prot)
-
+from . import utils
 
-def get_tenant_profile_client(protocol):
-    multiplex_prot = TMultiplexedProtocol(protocol, TENANT_PROFILE_CPI_NAME)
-    return TenantProfileService.Client(multiplex_prot)
-
-
-def get_user_profile_client(protocol):
-    multiplex_prot = TMultiplexedProtocol(protocol, USER_PROFILE_CPI_NAME)
-    return UserProfileService.Client(multiplex_prot)
+logger = logging.getLogger(__name__)
 
 
 def airavata_client(get_response):
@@ -99,25 +13,16 @@ def airavata_client(get_response):
 
         # If user is logged in create an airavata api client for the request
         if request.user.is_authenticated:
-            transport = get_transport(settings.AIRAVATA_API_HOST, settings.AIRAVATA_API_PORT,
settings.AIRAVATA_API_SECURE)
-            airavata_client = get_airavata_client(transport)
-
             try:
-                transport.open()
-            except Exception as e:
+                with utils.airavata_client() as airavata_client:
+                    request.airavata_client = airavata_client
+                    response = get_response(request)
+            except utils.ThriftConnectionException as e:
                 logger.exception("Failed to open thrift connection to API server")
-
-            if transport.isOpen():
-                request.airavata_client = airavata_client
-            else:
                 # if request.airavata_client is None, this will indicate to view
                 # code that the API server is down
                 request.airavata_client = None
-
-            response = get_response(request)
-
-            if transport.isOpen():
-                transport.close()
+                response = get_response(request)
         else:
             response = get_response(request)
 
@@ -125,32 +30,25 @@ def airavata_client(get_response):
 
     return middleware
 
+
 def sharing_client(get_response):
     "Open and close Sharing registry client for each request"
 
     def middleware(request):
 
-        # If user is logged in create an airavata api client for the request
+        # If user is logged in create a sharing registry client for the request
         if request.user.is_authenticated:
-            transport = get_transport(settings.SHARING_API_HOST, settings.SHARING_API_PORT,
settings.SHARING_API_SECURE)
-            sharing_client = get_sharing_client(transport)
-
             try:
-                transport.open()
-            except Exception as e:
-                logger.exception("Failed to open thrift connection to Sharing Registry server")
-
-            if transport.isOpen():
-                request.sharing_client = sharing_client
-            else:
+                with utils.sharing_client() as sharing_client:
+                    request.sharing_client = sharing_client
+                    response = get_response(request)
+            except utils.ThriftConnectionException as e:
+                logger.exception("Failed to open thrift connection to"
+                                 "Sharing Registry server")
                 # if request.sharing_client is None, this will indicate to view
                 # code that the Sharing server is down
                 request.sharing_client = None
-
-            response = get_response(request)
-
-            if transport.isOpen():
-                transport.close()
+                response = get_response(request)
         else:
             response = get_response(request)
 
@@ -168,39 +66,27 @@ def profile_service_client(get_response):
     """
     def middleware(request):
 
-        # If user is logged in create a profile service client for the request
+        # If user is logged in create an profile service client for the request
         if request.user.is_authenticated:
-            transport = get_transport(settings.PROFILE_SERVICE_HOST,
-                                      settings.PROFILE_SERVICE_PORT,
-                                      settings.PROFILE_SERVICE_SECURE)
-            binary_prot = get_binary_protocol(transport)
-            group_manager_client = get_group_manager_client(binary_prot)
-            iam_admin_client = get_iamadmin_client(binary_prot)
-            tenant_profile_client = get_tenant_profile_client(binary_prot)
-            user_profile_client = get_user_profile_client(binary_prot)
-
             try:
-                transport.open()
-            except Exception as e:
+                with utils.group_manager_client() as group_manager_client, \
+                     utils.iam_admin_client() as iam_admin_client, \
+                     utils.tenant_profile_client() as tenant_profile_client, \
+                     utils.user_profile_client() as user_profile_client:
+                    request.profile_service = {
+                        'group_manager': group_manager_client,
+                        'iam_admin': iam_admin_client,
+                        'tenant_profile': tenant_profile_client,
+                        'user_profile': user_profile_client,
+                    }
+                    response = get_response(request)
+            except utils.ThriftConnectionException as e:
                 logger.exception("Failed to open thrift connection to "
                                  "Profile Service server")
-
-            if transport.isOpen():
-                request.profile_service = {
-                    'group_manager': group_manager_client,
-                    'iam_admin': iam_admin_client,
-                    'tenant_profile': tenant_profile_client,
-                    'user_profile': user_profile_client,
-                }
-            else:
                 # if request.profile_service is None, this will indicate to
                 # view code that the Profile Service is down
                 request.profile_service = None
-
-            response = get_response(request)
-
-            if transport.isOpen():
-                transport.close()
+                response = get_response(request)
         else:
             response = get_response(request)
 
diff --git a/django_airavata/utils.py b/django_airavata/utils.py
new file mode 100644
index 0000000..53388d4
--- /dev/null
+++ b/django_airavata/utils.py
@@ -0,0 +1,175 @@
+import logging
+from contextlib import contextmanager
+
+from django.conf import settings
+from thrift.protocol import TBinaryProtocol
+from thrift.protocol.TMultiplexedProtocol import TMultiplexedProtocol
+from thrift.transport import TSocket, TSSLSocket, TTransport
+
+from airavata.api import Airavata
+from airavata.api.sharing import SharingRegistryService
+from airavata.service.profile.groupmanager.cpi import GroupManagerService
+from airavata.service.profile.groupmanager.cpi.constants import \
+    GROUP_MANAGER_CPI_NAME
+from airavata.service.profile.iam.admin.services.cpi import IamAdminServices
+from airavata.service.profile.iam.admin.services.cpi.constants import \
+    IAM_ADMIN_SERVICES_CPI_NAME
+from airavata.service.profile.tenant.cpi import TenantProfileService
+from airavata.service.profile.tenant.cpi.constants import \
+    TENANT_PROFILE_CPI_NAME
+from airavata.service.profile.user.cpi import UserProfileService
+from airavata.service.profile.user.cpi.constants import USER_PROFILE_CPI_NAME
+
+log = logging.getLogger(__name__)
+
+
+class ThriftConnectionException(Exception):
+    pass
+
+
+def get_unsecure_transport(hostname, port):
+    # Create a socket to the Airavata Server
+    transport = TSocket.TSocket(hostname, port)
+
+    # Use Buffered Protocol to speedup over raw sockets
+    transport = TTransport.TBufferedTransport(transport)
+    return transport
+
+
+def get_secure_transport(hostname, port):
+
+    # Create a socket to the Airavata Server
+    # TODO: validate server certificate
+    transport = TSSLSocket.TSSLSocket(hostname, port, validate=False)
+
+    # Use Buffered Protocol to speedup over raw sockets
+    transport = TTransport.TBufferedTransport(transport)
+    return transport
+
+
+def get_transport(hostname, port, secure=True):
+    if secure:
+        transport = get_secure_transport(hostname, port)
+    else:
+        transport = get_unsecure_transport(hostname, port)
+    return transport
+
+
+def get_airavata_client(transport):
+
+    # Airavata currently uses Binary Protocol
+    protocol = TBinaryProtocol.TBinaryProtocol(transport)
+
+    # Create a Airavata client to use the protocol encoder
+    client = Airavata.Client(protocol)
+    return client
+
+
+def get_sharing_client(transport):
+
+    protocol = TBinaryProtocol.TBinaryProtocol(transport)
+
+    return SharingRegistryService.Client(protocol)
+
+
+def get_binary_protocol(transport):
+    return TBinaryProtocol.TBinaryProtocol(transport)
+
+
+def get_group_manager_client(transport):
+    protocol = get_binary_protocol(transport)
+    multiplex_prot = TMultiplexedProtocol(protocol, GROUP_MANAGER_CPI_NAME)
+    return GroupManagerService.Client(multiplex_prot)
+
+
+def get_iamadmin_client(transport):
+    protocol = get_binary_protocol(transport)
+    multiplex_prot = TMultiplexedProtocol(protocol,
+                                          IAM_ADMIN_SERVICES_CPI_NAME)
+    return IamAdminServices.Client(multiplex_prot)
+
+
+def get_tenant_profile_client(transport):
+    protocol = get_binary_protocol(transport)
+    multiplex_prot = TMultiplexedProtocol(protocol, TENANT_PROFILE_CPI_NAME)
+    return TenantProfileService.Client(multiplex_prot)
+
+
+def get_user_profile_client(transport):
+    protocol = get_binary_protocol(transport)
+    multiplex_prot = TMultiplexedProtocol(protocol, USER_PROFILE_CPI_NAME)
+    return UserProfileService.Client(multiplex_prot)
+
+
+def airavata_client():
+    """Get Airavata API client as context manager (use in `with statement`)."""
+    return thrift_client(settings.AIRAVATA_API_HOST,
+                         settings.AIRAVATA_API_PORT,
+                         settings.AIRAVATA_API_SECURE,
+                         get_airavata_client)
+
+
+def sharing_client():
+    """Get Sharing API client as context manager (use in `with statement`)."""
+    return thrift_client(settings.SHARING_API_HOST,
+                         settings.SHARING_API_PORT,
+                         settings.SHARING_API_SECURE,
+                         get_airavata_client)
+
+
+def group_manager_client():
+    """Group Manager client as context manager (use in `with statement`)."""
+    return thrift_client(settings.PROFILE_SERVICE_HOST,
+                         settings.PROFILE_SERVICE_PORT,
+                         settings.PROFILE_SERVICE_SECURE,
+                         get_group_manager_client)
+
+
+def iam_admin_client():
+    """IAM Admin client as context manager (use in `with statement`)."""
+    return thrift_client(settings.PROFILE_SERVICE_HOST,
+                         settings.PROFILE_SERVICE_PORT,
+                         settings.PROFILE_SERVICE_SECURE,
+                         get_iamadmin_client)
+
+
+def tenant_profile_client():
+    """Tenant Profile client as context manager (use in `with statement`)."""
+    return thrift_client(settings.PROFILE_SERVICE_HOST,
+                         settings.PROFILE_SERVICE_PORT,
+                         settings.PROFILE_SERVICE_SECURE,
+                         get_tenant_profile_client)
+
+
+def user_profile_client():
+    """User Profile client as context manager (use in `with statement`)."""
+    return thrift_client(settings.PROFILE_SERVICE_HOST,
+                         settings.PROFILE_SERVICE_PORT,
+                         settings.PROFILE_SERVICE_SECURE,
+                         get_user_profile_client)
+
+
+@contextmanager
+def thrift_client(host, port, is_secure, client_generator):
+    transport = get_transport(host, port, is_secure)
+    client = client_generator(transport)
+
+    try:
+        transport.open()
+        log.debug("Thrift connection opened to {}:{}, "
+                  "secure={}".format(host, port, is_secure))
+        try:
+            yield client
+        except Exception as e:
+            log.exception("Thrift client error occurred")
+            raise e
+        finally:
+            if transport.isOpen():
+                transport.close()
+                log.debug("Thrift connection closed to {}:{}, "
+                          "secure={}".format(host, port, is_secure))
+    except Exception as e:
+        msg = "Failed to open thrift connection to {}:{}, secure={}".format(
+            host, port, is_secure)
+        log.debug(msg)
+        raise ThriftConnectionException(msg) from e


Mime
View raw message