Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explicitly passing a channel to GAPIC-generated API classes #2682

Merged
merged 2 commits into from
Nov 4, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 31 additions & 10 deletions core/google/cloud/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -620,8 +620,8 @@ def __call__(self, unused_context, callback):
callback(headers, None)


def make_secure_stub(credentials, user_agent, stub_class, host):
"""Makes a secure stub for an RPC service.
def make_secure_channel(credentials, user_agent, host):
"""Makes a secure channel for an RPC service.

Uses / depends on gRPC.

Expand All @@ -630,16 +630,13 @@ def make_secure_stub(credentials, user_agent, stub_class, host):
access tokens.

:type user_agent: str
:param user_agent: (Optional) The user agent to be used with API requests.

:type stub_class: type
:param stub_class: A gRPC stub type for a given service.
:param user_agent: The user agent to be used with API requests.

:type host: str
:param host: The host for the service.

:rtype: object, instance of ``stub_class``
:returns: The stub object used to make gRPC requests to a given API.
:rtype: :class:`grpc._channel.Channel`
:returns: gRPC secure channel with credentials attached.
"""
# ssl_channel_credentials() loads root certificates from
# `grpc/_adapter/credentials/roots.pem`.
Expand All @@ -653,8 +650,32 @@ def make_secure_stub(credentials, user_agent, stub_class, host):
channel_args = (
('grpc.primary_user_agent', user_agent),
)
channel = grpc.secure_channel(target, channel_creds,
options=channel_args)
return grpc.secure_channel(target, channel_creds,
options=channel_args)


def make_secure_stub(credentials, user_agent, stub_class, host):
"""Makes a secure stub for an RPC service.

Uses / depends on gRPC.

:type credentials: :class:`oauth2client.client.OAuth2Credentials`
:param credentials: The OAuth2 Credentials to use for creating
access tokens.

:type user_agent: str
:param user_agent: The user agent to be used with API requests.

:type stub_class: type
:param stub_class: A gRPC stub type for a given service.

:type host: str
:param host: The host for the service.

:rtype: object, instance of ``stub_class``
:returns: The stub object used to make gRPC requests to a given API.
"""
channel = make_secure_channel(credentials, user_agent, host)
return stub_class(channel)


Expand Down
56 changes: 41 additions & 15 deletions core/unit_tests/test__helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -917,20 +917,17 @@ def callback(*args):
self.assertEqual(len(credentials._tokens), 1)


class Test_make_secure_stub(unittest.TestCase):
class Test_make_secure_channel(unittest.TestCase):

def _callFUT(self, *args, **kwargs):
from google.cloud._helpers import make_secure_stub
return make_secure_stub(*args, **kwargs)
from google.cloud._helpers import make_secure_channel
return make_secure_channel(*args, **kwargs)

def test_it(self):
from six.moves import http_client
from google.cloud._testing import _Monkey
from google.cloud import _helpers as MUT

mock_result = object()
stub_inputs = []

SSL_CREDS = object()
METADATA_CREDS = object()
COMPOSITE_CREDS = object()
Expand Down Expand Up @@ -961,11 +958,6 @@ def secure_channel(self, *args, **kwargs):
return CHANNEL

grpc_mod = _GRPCModule()

def mock_stub_class(channel):
stub_inputs.append(channel)
return mock_result

metadata_plugin = object()
plugin_args = []

Expand All @@ -978,11 +970,9 @@ def mock_plugin(*args):
user_agent = 'USER_AGENT'
with _Monkey(MUT, grpc=grpc_mod,
MetadataPlugin=mock_plugin):
result = self._callFUT(credentials, user_agent,
mock_stub_class, host)
result = self._callFUT(credentials, user_agent, host)

self.assertIs(result, mock_result)
self.assertEqual(stub_inputs, [CHANNEL])
self.assertIs(result, CHANNEL)
self.assertEqual(plugin_args, [(credentials,)])
self.assertEqual(grpc_mod.ssl_channel_credentials_args, ())
self.assertEqual(grpc_mod.metadata_call_credentials_args,
Expand All @@ -999,6 +989,42 @@ def mock_plugin(*args):
(secure_args, secure_kwargs))


class Test_make_secure_stub(unittest.TestCase):

def _callFUT(self, *args, **kwargs):
from google.cloud._helpers import make_secure_stub
return make_secure_stub(*args, **kwargs)

def test_it(self):
from google.cloud._testing import _Monkey
from google.cloud import _helpers as MUT

result = object()
channel_obj = object()
channels = []
channel_args = []

def stub_class(channel):
channels.append(channel)
return result

def mock_channel(*args):
channel_args.append(args)
return channel_obj

credentials = object()
user_agent = 'you-sir-age-int'
host = 'localhost'
with _Monkey(MUT, make_secure_channel=mock_channel):
stub = self._callFUT(credentials, user_agent,
stub_class, host)

self.assertIs(stub, result)
self.assertEqual(channels, [channel_obj])
self.assertEqual(channel_args,
[(credentials, user_agent, host)])


class Test_make_insecure_stub(unittest.TestCase):

def _callFUT(self, *args, **kwargs):
Expand Down
56 changes: 56 additions & 0 deletions logging/google/cloud/logging/_gax.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@

import functools

from google.cloud.gapic.logging.v2.config_service_v2_api import (
ConfigServiceV2Api)
from google.cloud.gapic.logging.v2.logging_service_v2_api import (
LoggingServiceV2Api)
from google.cloud.gapic.logging.v2.metrics_service_v2_api import (
MetricsServiceV2Api)
from google.gax import CallOptions
from google.gax import INITIAL_PAGE
from google.gax.errors import GaxError
Expand All @@ -28,6 +34,8 @@
from grpc import StatusCode

from google.cloud._helpers import _datetime_to_rfc3339
from google.cloud._helpers import make_secure_channel
from google.cloud.connection import DEFAULT_USER_AGENT
from google.cloud.exceptions import Conflict
from google.cloud.exceptions import NotFound
from google.cloud.iterator import GAXIterator
Expand Down Expand Up @@ -511,3 +519,51 @@ def _item_to_metric(iterator, log_metric_pb):
"""
resource = MessageToDict(log_metric_pb)
return Metric.from_api_repr(resource, iterator.client)


def make_gax_logging_api(client):
"""Create an instance of the GAX Logging API.
:type client: :class:`~google.cloud.logging.client.Client`
:param client: The client that holds configuration details.
:rtype: :class:`_LoggingAPI`
:returns: A metrics API instance with the proper credentials.
"""
channel = make_secure_channel(
client.connection.credentials, DEFAULT_USER_AGENT,
LoggingServiceV2Api.SERVICE_ADDRESS)
generated = LoggingServiceV2Api(channel=channel)
return _LoggingAPI(generated, client)


def make_gax_metrics_api(client):
"""Create an instance of the GAX Metrics API.
:type client: :class:`~google.cloud.logging.client.Client`
:param client: The client that holds configuration details.
:rtype: :class:`_MetricsAPI`
:returns: A metrics API instance with the proper credentials.
"""
channel = make_secure_channel(
client.connection.credentials, DEFAULT_USER_AGENT,
MetricsServiceV2Api.SERVICE_ADDRESS)
generated = MetricsServiceV2Api(channel=channel)
return _MetricsAPI(generated, client)


def make_gax_sinks_api(client):
"""Create an instance of the GAX Sinks API.
:type client: :class:`~google.cloud.logging.client.Client`
:param client: The client that holds configuration details.
:rtype: :class:`_SinksAPI`
:returns: A metrics API instance with the proper credentials.
"""
channel = make_secure_channel(
client.connection.credentials, DEFAULT_USER_AGENT,
ConfigServiceV2Api.SERVICE_ADDRESS)
generated = ConfigServiceV2Api(channel=channel)
return _SinksAPI(generated, client)
27 changes: 9 additions & 18 deletions logging/google/cloud/logging/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,14 @@
import os

try:
from google.cloud.gapic.logging.v2.config_service_v2_api import (
ConfigServiceV2Api as GeneratedSinksAPI)
from google.cloud.gapic.logging.v2.logging_service_v2_api import (
LoggingServiceV2Api as GeneratedLoggingAPI)
from google.cloud.gapic.logging.v2.metrics_service_v2_api import (
MetricsServiceV2Api as GeneratedMetricsAPI)
from google.cloud.logging._gax import _LoggingAPI as GAXLoggingAPI
from google.cloud.logging._gax import _MetricsAPI as GAXMetricsAPI
from google.cloud.logging._gax import _SinksAPI as GAXSinksAPI
from google.cloud.logging._gax import make_gax_logging_api
from google.cloud.logging._gax import make_gax_metrics_api
from google.cloud.logging._gax import make_gax_sinks_api
except ImportError: # pragma: NO COVER
_HAVE_GAX = False
GeneratedLoggingAPI = GAXLoggingAPI = None
GeneratedMetricsAPI = GAXMetricsAPI = None
GeneratedSinksAPI = GAXSinksAPI = None
make_gax_logging_api = None
make_gax_metrics_api = None
make_gax_sinks_api = None
else:
_HAVE_GAX = True

Expand Down Expand Up @@ -97,8 +91,7 @@ def logging_api(self):
"""
if self._logging_api is None:
if self._use_gax:
generated = GeneratedLoggingAPI()
self._logging_api = GAXLoggingAPI(generated, self)
self._logging_api = make_gax_logging_api(self)
else:
self._logging_api = JSONLoggingAPI(self)
return self._logging_api
Expand All @@ -112,8 +105,7 @@ def sinks_api(self):
"""
if self._sinks_api is None:
if self._use_gax:
generated = GeneratedSinksAPI()
self._sinks_api = GAXSinksAPI(generated, self)
self._sinks_api = make_gax_sinks_api(self)
else:
self._sinks_api = JSONSinksAPI(self)
return self._sinks_api
Expand All @@ -127,8 +119,7 @@ def metrics_api(self):
"""
if self._metrics_api is None:
if self._use_gax:
generated = GeneratedMetricsAPI()
self._metrics_api = GAXMetricsAPI(generated, self)
self._metrics_api = make_gax_metrics_api(self)
else:
self._metrics_api = JSONMetricsAPI(self)
return self._metrics_api
Expand Down
Loading