Skip to content

Commit

Permalink
feat(pubsub): enable project autodetection and detect empty project (#…
Browse files Browse the repository at this point in the history
…8168)

* feat(pubsub): enable project autodetection and detect empty project

* test client.Project() as well
  • Loading branch information
hongalex committed Jun 27, 2023
1 parent 2727590 commit c7e05d8
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 0 deletions.
22 changes: 22 additions & 0 deletions pubsub/integration_test.go
Expand Up @@ -2060,3 +2060,25 @@ func TestIntegration_TopicUpdateSchema(t *testing.T) {
t.Fatalf("schema settings for update -want, +got: %v", diff)
}
}

func TestIntegration_DetectProjectID(t *testing.T) {
ctx := context.Background()
testCreds := testutil.Credentials(ctx)
if testCreds == nil {
t.Skip("test credentials not present, skipping")
}

goodClient, err := NewClient(ctx, DetectProjectID, option.WithCredentials(testCreds))
if err != nil {
t.Errorf("test pubsub.NewClient: %v", err)
}
if goodClient.Project() != testutil.ProjID() {
t.Errorf("client.Project() got %q, want %q", goodClient.Project(), testutil.ProjID())
}

badTS := testutil.ErroringTokenSource{}

if badClient, err := NewClient(ctx, DetectProjectID, option.WithTokenSource(badTS)); err == nil {
t.Errorf("expected error from bad token source, NewClient succeeded with project: %s", badClient.projectID)
}
}
32 changes: 32 additions & 0 deletions pubsub/pubsub.go
Expand Up @@ -16,13 +16,15 @@ package pubsub // import "cloud.google.com/go/pubsub"

import (
"context"
"errors"
"fmt"
"os"
"reflect"
"runtime"
"strings"
"time"

"cloud.google.com/go/internal/detect"
vkit "cloud.google.com/go/pubsub/apiv1"
"cloud.google.com/go/pubsub/internal"
gax "github.com/googleapis/gax-go/v2"
Expand Down Expand Up @@ -113,13 +115,30 @@ func mergeSubscriberCallOptions(a *vkit.SubscriberCallOptions, b *vkit.Subscribe
return res
}

// DetectProjectID is a sentinel value that instructs NewClient to detect the
// project ID. It is given in place of the projectID argument. NewClient will
// use the project ID from the given credentials or the default credentials
// (https://developers.google.com/accounts/docs/application-default-credentials)
// if no credentials were provided. When providing credentials, not all
// options will allow NewClient to extract the project ID. Specifically a JWT
// does not have the project ID encoded.
const DetectProjectID = "*detect-project-id*"

// ErrEmptyProjectID denotes that the project string passed into NewClient was empty.
// Please provide a valid project ID or use the DetectProjectID sentinel value to detect
// project ID from well defined sources.
var ErrEmptyProjectID = errors.New("pubsub: projectID string is empty")

// NewClient creates a new PubSub client. It uses a default configuration.
func NewClient(ctx context.Context, projectID string, opts ...option.ClientOption) (c *Client, err error) {
return NewClientWithConfig(ctx, projectID, nil, opts...)
}

// NewClientWithConfig creates a new PubSub client.
func NewClientWithConfig(ctx context.Context, projectID string, config *ClientConfig, opts ...option.ClientOption) (c *Client, err error) {
if projectID == "" {
return nil, ErrEmptyProjectID
}
var o []option.ClientOption
// Environment variables for gcloud emulator:
// https://cloud.google.com/sdk/gcloud/reference/beta/emulators/pubsub/
Expand Down Expand Up @@ -157,13 +176,26 @@ func NewClientWithConfig(ctx context.Context, projectID string, config *ClientCo
subc.CallOptions = mergeSubscriberCallOptions(subc.CallOptions, config.SubscriberCallOptions)
}
pubc.SetGoogleClientInfo("gccl", internal.Version)

// Handle project autodetection.
projectID, err = detect.ProjectID(ctx, projectID, "", opts...)
if err != nil {
return nil, err
}

return &Client{
projectID: projectID,
pubc: pubc,
subc: subc,
}, nil
}

// Project returns the project ID or number for this instance of the client, which may have
// either been explicitly specified or autodetected.
func (c *Client) Project() string {
return c.projectID
}

// Close releases any resources held by the client,
// such as memory and goroutines.
//
Expand Down
8 changes: 8 additions & 0 deletions pubsub/pubsub_test.go
Expand Up @@ -117,3 +117,11 @@ func TestClient_ApplyClientConfig(t *testing.T) {
}
}
}

func TestClient_EmptyProjectID(t *testing.T) {
ctx := context.Background()
_, err := NewClient(ctx, "")
if err != ErrEmptyProjectID {
t.Fatalf("passing empty project ID got %v, want%v", err, ErrEmptyProjectID)
}
}

0 comments on commit c7e05d8

Please sign in to comment.