@@ -16,13 +16,15 @@ package pubsub // import "cloud.google.com/go/pubsub"
1616
1717import (
1818 "context"
19+ "errors"
1920 "fmt"
2021 "os"
2122 "reflect"
2223 "runtime"
2324 "strings"
2425 "time"
2526
27+ "cloud.google.com/go/internal/detect"
2628 vkit "cloud.google.com/go/pubsub/apiv1"
2729 "cloud.google.com/go/pubsub/internal"
2830 gax "github.com/googleapis/gax-go/v2"
@@ -113,13 +115,30 @@ func mergeSubscriberCallOptions(a *vkit.SubscriberCallOptions, b *vkit.Subscribe
113115 return res
114116}
115117
118+ // DetectProjectID is a sentinel value that instructs NewClient to detect the
119+ // project ID. It is given in place of the projectID argument. NewClient will
120+ // use the project ID from the given credentials or the default credentials
121+ // (https://developers.google.com/accounts/docs/application-default-credentials)
122+ // if no credentials were provided. When providing credentials, not all
123+ // options will allow NewClient to extract the project ID. Specifically a JWT
124+ // does not have the project ID encoded.
125+ const DetectProjectID = "*detect-project-id*"
126+
127+ // ErrEmptyProjectID denotes that the project string passed into NewClient was empty.
128+ // Please provide a valid project ID or use the DetectProjectID sentinel value to detect
129+ // project ID from well defined sources.
130+ var ErrEmptyProjectID = errors .New ("pubsub: projectID string is empty" )
131+
116132// NewClient creates a new PubSub client. It uses a default configuration.
117133func NewClient (ctx context.Context , projectID string , opts ... option.ClientOption ) (c * Client , err error ) {
118134 return NewClientWithConfig (ctx , projectID , nil , opts ... )
119135}
120136
121137// NewClientWithConfig creates a new PubSub client.
122138func NewClientWithConfig (ctx context.Context , projectID string , config * ClientConfig , opts ... option.ClientOption ) (c * Client , err error ) {
139+ if projectID == "" {
140+ return nil , ErrEmptyProjectID
141+ }
123142 var o []option.ClientOption
124143 // Environment variables for gcloud emulator:
125144 // https://cloud.google.com/sdk/gcloud/reference/beta/emulators/pubsub/
@@ -157,13 +176,26 @@ func NewClientWithConfig(ctx context.Context, projectID string, config *ClientCo
157176 subc .CallOptions = mergeSubscriberCallOptions (subc .CallOptions , config .SubscriberCallOptions )
158177 }
159178 pubc .SetGoogleClientInfo ("gccl" , internal .Version )
179+
180+ // Handle project autodetection.
181+ projectID , err = detect .ProjectID (ctx , projectID , "" , opts ... )
182+ if err != nil {
183+ return nil , err
184+ }
185+
160186 return & Client {
161187 projectID : projectID ,
162188 pubc : pubc ,
163189 subc : subc ,
164190 }, nil
165191}
166192
193+ // Project returns the project ID or number for this instance of the client, which may have
194+ // either been explicitly specified or autodetected.
195+ func (c * Client ) Project () string {
196+ return c .projectID
197+ }
198+
167199// Close releases any resources held by the client,
168200// such as memory and goroutines.
169201//
0 commit comments