Skip to content

Commit dab7994

Browse files
committed
feat(otel): implement eager channel wrapping (Variant B) for OTel compatibility
1 parent bdef56b commit dab7994

2 files changed

Lines changed: 68 additions & 45 deletions

File tree

‎packages/google-cloud-secret-manager/google/cloud/secretmanager_v1/services/secret_manager_service/client.py‎

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -743,15 +743,6 @@ def __init__(
743743
if isinstance(transport, str) or transport is None
744744
else cast(Callable[..., SecretManagerServiceTransport], transport)
745745
)
746-
# Resolve interceptors for gRPC
747-
interceptors = None
748-
if transport_init is SecretManagerServiceGrpcTransport:
749-
otel_interceptor = _otel_helpers.get_otel_grpc_interceptor(
750-
self._client_options
751-
)
752-
if otel_interceptor:
753-
interceptors = [otel_interceptor]
754-
755746
# initialize with the provided callable or the passed in class
756747
transport_kwargs = {
757748
"credentials": credentials,
@@ -764,8 +755,27 @@ def __init__(
764755
"always_use_jwt_access": True,
765756
"api_audience": self._client_options.api_audience,
766757
}
767-
if interceptors is not None:
768-
transport_kwargs["interceptors"] = interceptors
758+
759+
# 🎯 VARIANT B: Eager Channel Creation and Tracing Application
760+
if transport_init is SecretManagerServiceGrpcTransport:
761+
if _otel_helpers.is_otel_capabilities_enabled(self._client_options):
762+
# Eagerly create the channel using the Transport's classmethod
763+
raw_channel = transport_init.create_channel(
764+
self._api_endpoint,
765+
credentials=credentials,
766+
credentials_file=self._client_options.credentials_file,
767+
scopes=self._client_options.scopes,
768+
quota_project_id=self._client_options.quota_project_id,
769+
)
770+
771+
# Apply OTel capabilities to the channel
772+
wrapped_channel = _otel_helpers.apply_otel_capabilities_to_channel(
773+
raw_channel,
774+
self._client_options
775+
)
776+
777+
# Inject the wrapped channel into transport kwargs
778+
transport_kwargs["channel"] = wrapped_channel
769779

770780
self._transport = transport_init(**transport_kwargs)
771781

‎packages/google-cloud-secret-manager/tests/unit/gapic/secretmanager_v1/test_secret_manager_service.py‎

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -769,47 +769,60 @@ def test_secret_manager_service_client_client_options(
769769
)
770770

771771

772-
def test_secret_manager_service_client_otel_interceptor_injection():
773-
# Mock the helper to return a sentinel interceptor
774-
mock_interceptor = mock.Mock()
772+
def test_secret_manager_service_client_otel_eager_channel_injection():
773+
# Mock the helpers to simulate OTel being enabled
774+
mock_raw_channel = mock.Mock()
775+
mock_wrapped_channel = mock.Mock()
775776

776777
with mock.patch(
777-
"google.cloud.secretmanager_v1.services.secret_manager_service.client._otel_helpers.get_otel_grpc_interceptor"
778-
) as mock_get_interceptor:
779-
mock_get_interceptor.return_value = mock_interceptor
780-
781-
with mock.patch.object(
782-
transports.SecretManagerServiceGrpcTransport, "__init__"
783-
) as patched_transport_init:
784-
patched_transport_init.return_value = None
785-
786-
client = SecretManagerServiceClient(transport="grpc")
787-
788-
mock_get_interceptor.assert_called_once()
789-
790-
called_kwargs = patched_transport_init.call_args.kwargs
791-
assert "interceptors" in called_kwargs
792-
assert called_kwargs["interceptors"] == [mock_interceptor]
793-
794-
795-
def test_secret_manager_service_client_otel_interceptor_injection_disabled():
796-
# The helper does not return an interceptor
778+
"google.cloud.secretmanager_v1.services.secret_manager_service.client._otel_helpers.is_otel_capabilities_enabled",
779+
return_value=True
780+
) as mock_is_enabled:
781+
with mock.patch(
782+
"google.cloud.secretmanager_v1.services.secret_manager_service.client._otel_helpers.apply_otel_capabilities_to_channel",
783+
return_value=mock_wrapped_channel
784+
) as mock_apply_otel:
785+
with mock.patch.object(
786+
transports.SecretManagerServiceGrpcTransport, "create_channel",
787+
return_value=mock_raw_channel
788+
) as mock_create_channel:
789+
with mock.patch.object(
790+
transports.SecretManagerServiceGrpcTransport, "__init__"
791+
) as patched_transport_init:
792+
patched_transport_init.return_value = None
793+
794+
client = SecretManagerServiceClient(transport="grpc")
795+
796+
mock_is_enabled.assert_called_once()
797+
mock_create_channel.assert_called_once()
798+
mock_apply_otel.assert_called_once_with(mock_raw_channel, mock.ANY)
799+
800+
called_kwargs = patched_transport_init.call_args.kwargs
801+
assert "channel" in called_kwargs
802+
assert called_kwargs["channel"] == mock_wrapped_channel
803+
804+
805+
def test_secret_manager_service_client_otel_eager_channel_injection_disabled():
806+
# Simulate OTel being disabled
797807
with mock.patch(
798-
"google.cloud.secretmanager_v1.services.secret_manager_service.client._otel_helpers.get_otel_grpc_interceptor"
799-
) as mock_get_interceptor:
800-
mock_get_interceptor.return_value = None
801-
808+
"google.cloud.secretmanager_v1.services.secret_manager_service.client._otel_helpers.is_otel_capabilities_enabled",
809+
return_value=False
810+
) as mock_is_enabled:
802811
with mock.patch.object(
803-
transports.SecretManagerServiceGrpcTransport, "__init__"
804-
) as patched_transport_init:
805-
patched_transport_init.return_value = None
812+
transports.SecretManagerServiceGrpcTransport, "create_channel"
813+
) as mock_create_channel:
814+
with mock.patch.object(
815+
transports.SecretManagerServiceGrpcTransport, "__init__"
816+
) as patched_transport_init:
817+
patched_transport_init.return_value = None
806818

807-
client = SecretManagerServiceClient(transport="grpc")
819+
client = SecretManagerServiceClient(transport="grpc")
808820

809-
mock_get_interceptor.assert_called_once()
821+
mock_is_enabled.assert_called_once()
822+
mock_create_channel.assert_not_called()
810823

811-
called_kwargs = patched_transport_init.call_args.kwargs
812-
assert "interceptors" not in called_kwargs
824+
called_kwargs = patched_transport_init.call_args.kwargs
825+
assert "channel" not in called_kwargs
813826

814827

815828
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)