Skip to content

Integration PubSub Extension

Aryeh Citron edited this page Apr 22, 2026 · 13 revisions

Integration: Google Cloud Pub/Sub Extension

Track Google Cloud Pub/Sub operations in your test diagrams using the TestTrackingDiagrams.Extensions.PubSub NuGet package. This extension wraps PublisherClient and SubscriberClient to capture publish/subscribe operations.

Using a shared library or abstraction layer? If your code doesn't use the Pub/Sub SDK directly — e.g. it goes through a shared messaging library, wrapper, or custom abstraction — this extension won't be able to intercept the underlying calls. See Tracking Custom Dependencies for alternative approaches including MessageTracker and TrackingProxy<T>.

Installation

dotnet add package TestTrackingDiagrams.Extensions.PubSub

Quick Start

Publisher

using TestTrackingDiagrams.Extensions.PubSub;

var publisher = await PublisherClient.CreateAsync(topicName);
var trackingPublisher = new TrackingPublisherClient(publisher, new PubSubTrackingOptions
{
    ServiceName = "PubSub",
    CallingServiceName = "OrdersApi",
    CurrentTestInfoFetcher = () => (TestContext.CurrentTestName, TestContext.CurrentTestId)
});

await trackingPublisher.PublishAsync("Hello, Pub/Sub!");

Subscriber

var subscriber = await SubscriberClient.CreateAsync(subscriptionName);
var trackingSubscriber = new TrackingSubscriberClient(subscriber, new PubSubTrackingOptions
{
    ServiceName = "PubSub",
    CallingServiceName = "WorkerService",
    CurrentTestInfoFetcher = () => (TestContext.CurrentTestName, TestContext.CurrentTestId)
});

await trackingSubscriber.StartAsync(async (msg, ct) =>
{
    // Process message
    return SubscriberClient.Reply.Ack;
});

How It Works

Google Cloud Pub/Sub uses gRPC internally, so DelegatingHandler interception is not viable. Instead, this extension uses a wrapper/decorator pattern:

  • TrackingPublisherClient wraps PublisherClient and logs publish operations
  • TrackingSubscriberClient wraps SubscriberClient and intercepts the message handler callback

PubSubTracker

Both wrappers use PubSubTracker as a central logging helper. It implements ITrackingComponent and handles request/response logging with RequestResponseMetaType.Event for messaging semantics.

Supported Operations

Operation Enum Value Source
Publish (single) PubSubOperation.Publish TrackingPublisherClient
Publish (batch) PubSubOperation.PublishBatch TrackingPublisherClient
Receive PubSubOperation.Receive TrackingSubscriberClient callback
Pull PubSubOperation.Pull Low-level API
Acknowledge PubSubOperation.Acknowledge Low-level API
ModifyAckDeadline PubSubOperation.ModifyAckDeadline Low-level API
StartSubscriber PubSubOperation.StartSubscriber Lifecycle
StopSubscriber PubSubOperation.StopSubscriber Lifecycle

Resource Name Extraction

GCP Pub/Sub uses full resource paths like projects/my-project/topics/my-topic. At Detailed verbosity, short names are extracted:

  • projects/my-project/topics/my-topicmy-topic
  • projects/my-project/subscriptions/my-submy-sub

Verbosity Levels

PubSubTrackingVerbosity.Summarised

  • Label: Operation name (e.g. Publish)
  • Content: Omitted
  • URI: pubsub:///my-topic

PubSubTrackingVerbosity.Detailed

  • Label: Operation with target (e.g. Publish → my-topic, Receive ← my-sub)
  • Content: Message data (UTF-8 text)
  • URI: pubsub:///my-topic

PubSubTrackingVerbosity.Raw

  • Label: Full info including resource paths
  • Content: Message data + response details
  • URI: pubsub:///projects/p/topics/my-topic

Configuration

new PubSubTrackingOptions
{
    ServiceName = "PubSub",
    CallingServiceName = "OrdersApi",
    Verbosity = PubSubTrackingVerbosity.Detailed,
    CurrentTestInfoFetcher = () => (testName, testId)
}

ITrackingComponent

PubSubTracker implements ITrackingComponent and auto-registers:

  • ComponentName: "PubSubTracker ({ServiceName})"
  • WasInvoked: true after first operation
  • InvocationCount: Total operations logged

See Also

Home


Demo


Getting Started

Common Tasks

Integration Guides

Extensions

Configuration

Features

Reference

Clone this wiki locally