cloud: delete deprecated context, pubsub and container funcs
The pubsub and container packages now use Client types which must be
used in place of the legacy top-level functions.
The WithContext and NewContext functions were only needed for this
legacy API pattern; the new Client pattern can use regular contexts from
the golang.org/x/net/context package directly.
Fixes #297
Change-Id: I84f2dc0d7cc70fef4c29c6ab89be2196ba8c2243
Reviewed-on: https://code-review.googlesource.com/5420
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Dave Day <djd@golang.org>
diff --git a/container/legacy.go b/container/legacy.go
deleted file mode 100644
index f30a25b..0000000
--- a/container/legacy.go
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package container
-
-import (
- "errors"
- "net/http"
-
- "cloud.google.com/go/internal"
- "golang.org/x/net/context"
- raw "google.golang.org/api/container/v1"
-)
-
-// Cluster returns metadata about the specified cluster.
-//
-// Deprecated: please use Client.Cluster instead.
-func Cluster(ctx context.Context, zone, name string) (*Resource, error) {
- s := rawService(ctx)
- resp, err := s.Projects.Zones.Clusters.Get(internal.ProjID(ctx), zone, name).Do()
- if err != nil {
- return nil, err
- }
- return resourceFromRaw(resp), nil
-}
-
-// CreateCluster creates a new cluster with the provided metadata
-// in the specified zone.
-//
-// Deprecated: please use Client.CreateCluster instead.
-func CreateCluster(ctx context.Context, zone string, resource *Resource) (*Resource, error) {
- panic("not implemented")
-}
-
-// DeleteCluster deletes a cluster.
-//
-// Deprecated: please use Client.DeleteCluster instead.
-func DeleteCluster(ctx context.Context, zone, name string) error {
- s := rawService(ctx)
- _, err := s.Projects.Zones.Clusters.Delete(internal.ProjID(ctx), zone, name).Do()
- return err
-}
-
-// Operations returns a list of operations from the specified zone.
-// If no zone is specified, it looks up for all of the operations
-// that are running under the user's project.
-//
-// Deprecated: please use Client.Operations instead.
-func Operations(ctx context.Context, zone string) ([]*Op, error) {
- s := rawService(ctx)
- if zone == "" {
- resp, err := s.Projects.Zones.Operations.List(internal.ProjID(ctx), "-").Do()
- if err != nil {
- return nil, err
- }
- return opsFromRaw(resp.Operations), nil
- }
- resp, err := s.Projects.Zones.Operations.List(internal.ProjID(ctx), zone).Do()
- if err != nil {
- return nil, err
- }
- return opsFromRaw(resp.Operations), nil
-}
-
-// Operation returns an operation.
-//
-// Deprecated: please use Client.Operation instead.
-func Operation(ctx context.Context, zone, name string) (*Op, error) {
- s := rawService(ctx)
- resp, err := s.Projects.Zones.Operations.Get(internal.ProjID(ctx), zone, name).Do()
- if err != nil {
- return nil, err
- }
- if resp.StatusMessage != "" {
- return nil, errors.New(resp.StatusMessage)
- }
- return opFromRaw(resp), nil
-}
-
-func rawService(ctx context.Context) *raw.Service {
- return internal.Service(ctx, "container", func(hc *http.Client) interface{} {
- svc, _ := raw.New(hc)
- return svc
- }).(*raw.Service)
-}
diff --git a/example_test.go b/example_test.go
deleted file mode 100644
index 30d7496..0000000
--- a/example_test.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package cloud_test
-
-import (
- "io/ioutil"
- "log"
-
- "cloud.google.com/go/pubsub"
- "golang.org/x/net/context"
- "golang.org/x/oauth2/google"
- "google.golang.org/api/option"
-)
-
-func Example_createClientWithApplicationDefaultCredentials(ctx context.Context) *pubsub.Client {
- // Create a pubsub Client to demonstrate using Application Default
- // Credentials for authentication.
- //
- // Application Default Credentials provide a simple way to get
- // authorization credentials for use in calling Google APIs. They are
- // best suited for cases when the call needs to have the same identity
- // and authorization level for the application independent of the user.
- // This is the recommended approach to authorize calls to Google Cloud
- // APIs, particularly when you're building an application that is
- // deployed to Google App Engine or Google Compute Engine virtual
- // machines.
- // See
- // https://developers.google.com/identity/protocols/application-default-credentials
- // for more information.
- //
- // The same approach may be used to construct Clients from other
- // packages, e.g. bigtable, datastore.
- client, err := pubsub.NewClient(ctx, "project-id")
- if err != nil {
- log.Fatal("new client:", err)
- }
-
- return client
-}
-
-func Example_createClientWithTokenSource(ctx context.Context) *pubsub.Client {
- jsonKey, err := ioutil.ReadFile("/path/to/json/keyfile.json")
- if err != nil {
- log.Fatal(err)
- }
- conf, err := google.JWTConfigFromJSON(
- jsonKey,
- pubsub.ScopeCloudPlatform,
- pubsub.ScopePubSub,
- )
-
- if err != nil {
- log.Fatal(err)
- }
- ts := conf.TokenSource(ctx)
-
- // Create a pubsub Client to demonstrate using an OAuth2 token source
- // for authentication. The same approach may be used to construct
- // Clients from other packages, e.g. bigtable, datastore.
- client, err := pubsub.NewClient(ctx, "project-id", option.WithTokenSource(ts))
- if err != nil {
- log.Fatal("new client:", err)
- }
-
- return client
-}
diff --git a/internal/cloud.go b/internal/cloud.go
index 5942880..8e0c8f8 100644
--- a/internal/cloud.go
+++ b/internal/cloud.go
@@ -20,63 +20,16 @@
import (
"fmt"
"net/http"
- "sync"
-
- "golang.org/x/net/context"
)
-type contextKey struct{}
-
-func WithContext(parent context.Context, projID string, c *http.Client) context.Context {
- if c == nil {
- panic("nil *http.Client passed to WithContext")
- }
- if projID == "" {
- panic("empty project ID passed to WithContext")
- }
- return context.WithValue(parent, contextKey{}, &cloudContext{
- ProjectID: projID,
- HTTPClient: c,
- })
-}
-
const userAgent = "gcloud-golang/0.1"
-type cloudContext struct {
- ProjectID string
- HTTPClient *http.Client
-
- mu sync.Mutex // guards svc
- svc map[string]interface{} // e.g. "storage" => *rawStorage.Service
-}
-
-// Service returns the result of the fill function if it's never been
-// called before for the given name (which is assumed to be an API
-// service name, like "datastore"). If it has already been cached, the fill
-// func is not run.
-// It's safe for concurrent use by multiple goroutines.
-func Service(ctx context.Context, name string, fill func(*http.Client) interface{}) interface{} {
- return cc(ctx).service(name, fill)
-}
-
-func (c *cloudContext) service(name string, fill func(*http.Client) interface{}) interface{} {
- c.mu.Lock()
- defer c.mu.Unlock()
-
- if c.svc == nil {
- c.svc = make(map[string]interface{})
- } else if v, ok := c.svc[name]; ok {
- return v
- }
- v := fill(c.HTTPClient)
- c.svc[name] = v
- return v
-}
-
-// Transport is an http.RoundTripper that appends
-// Google Cloud client's user-agent to the original
-// request's user-agent header.
+// Transport is an http.RoundTripper that appends Google Cloud client's
+// user-agent to the original request's user-agent header.
type Transport struct {
+ // TODO(bradfitz): delete internal.Transport. It's too wrappy for what it does.
+ // Do User-Agent some other way.
+
// Base is the actual http.RoundTripper
// requests will use. It must not be nil.
Base http.RoundTripper
@@ -109,20 +62,3 @@
}
return r2
}
-
-func ProjID(ctx context.Context) string {
- return cc(ctx).ProjectID
-}
-
-func HTTPClient(ctx context.Context) *http.Client {
- return cc(ctx).HTTPClient
-}
-
-// cc returns the internal *cloudContext (cc) state for a context.Context.
-// It panics if the user did it wrong.
-func cc(ctx context.Context) *cloudContext {
- if c, ok := ctx.Value(contextKey{}).(*cloudContext); ok {
- return c
- }
- panic("invalid context.Context type; it should be created with cloud.NewContext")
-}
diff --git a/pubsub/legacy.go b/pubsub/legacy.go
deleted file mode 100644
index 75bcbbe..0000000
--- a/pubsub/legacy.go
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright 2016 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package pubsub
-
-import (
- "encoding/base64"
- "errors"
- "fmt"
- "net/http"
- "os"
- "time"
-
- "cloud.google.com/go/internal"
- "golang.org/x/net/context"
- "google.golang.org/api/googleapi"
- raw "google.golang.org/api/pubsub/v1"
-)
-
-// batchLimit is maximun size of a single batch.
-const batchLimit = 1000
-
-// CreateTopic creates a new topic with the specified name on the backend.
-//
-// Deprecated: Use Client.NewTopic instead.
-//
-// It will return an error if topic already exists.
-func CreateTopic(ctx context.Context, name string) error {
- _, err := rawService(ctx).Projects.Topics.Create(fullTopicName(internal.ProjID(ctx), name), &raw.Topic{}).Do()
- return err
-}
-
-// DeleteTopic deletes the specified topic.
-//
-// Deprecated: Use Topic.Delete instead.
-func DeleteTopic(ctx context.Context, name string) error {
- _, err := rawService(ctx).Projects.Topics.Delete(fullTopicName(internal.ProjID(ctx), name)).Do()
- return err
-}
-
-// TopicExists returns true if a topic exists with the specified name.
-//
-// Deprecated: Use Topic.Exists instead.
-func TopicExists(ctx context.Context, name string) (bool, error) {
- _, err := rawService(ctx).Projects.Topics.Get(fullTopicName(internal.ProjID(ctx), name)).Do()
- if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound {
- return false, nil
- }
- if err != nil {
- return false, err
- }
- return true, nil
-}
-
-// DeleteSub deletes the subscription.
-//
-// Deprecated: Use Subscription.Delete instead.
-func DeleteSub(ctx context.Context, name string) error {
- _, err := rawService(ctx).Projects.Subscriptions.Delete(fullSubName(internal.ProjID(ctx), name)).Do()
- return err
-}
-
-// SubExists returns true if subscription exists.
-//
-// Deprecated: Use Subscription.Exists instead.
-func SubExists(ctx context.Context, name string) (bool, error) {
- _, err := rawService(ctx).Projects.Subscriptions.Get(fullSubName(internal.ProjID(ctx), name)).Do()
- if e, ok := err.(*googleapi.Error); ok && e.Code == http.StatusNotFound {
- return false, nil
- }
- if err != nil {
- return false, err
- }
- return true, nil
-}
-
-// CreateSub creates a Pub/Sub subscription on the backend.
-//
-// Deprecated: Use Client.NewSubscription instead.
-//
-// A subscription should subscribe to an existing topic.
-//
-// The messages that haven't acknowledged will be pushed back to the
-// subscription again when the default acknowledgement deadline is
-// reached. You can override the default deadline by providing a
-// non-zero deadline. Deadline must not be specified to
-// precision greater than one second.
-//
-// As new messages are being queued on the subscription, you
-// may recieve push notifications regarding to the new arrivals.
-// To receive notifications of new messages in the queue,
-// specify an endpoint callback URL.
-// If endpoint is an empty string the backend will not notify the
-// client of new messages.
-//
-// If the subscription already exists an error will be returned.
-func CreateSub(ctx context.Context, name string, topic string, deadline time.Duration, endpoint string) error {
- sub := &raw.Subscription{
- Topic: fullTopicName(internal.ProjID(ctx), topic),
- }
- if int64(deadline) > 0 {
- if !isSec(deadline) {
- return errors.New("pubsub: deadline must not be specified to precision greater than one second")
- }
- sub.AckDeadlineSeconds = int64(deadline / time.Second)
- }
- if endpoint != "" {
- sub.PushConfig = &raw.PushConfig{PushEndpoint: endpoint}
- }
- _, err := rawService(ctx).Projects.Subscriptions.Create(fullSubName(internal.ProjID(ctx), name), sub).Do()
- return err
-}
-
-// Pull pulls up to n messages from the subscription. n must not be larger than 100.
-//
-// Deprecated: Use Subscription.Pull instead
-func Pull(ctx context.Context, sub string, n int) ([]*Message, error) {
- return pull(ctx, sub, n, true)
-}
-
-// PullWait pulls up to n messages from the subscription. If there are no
-// messages in the queue, it will wait until at least one message is
-// available or a timeout occurs. n must not be larger than 100.
-//
-// Deprecated: Use Subscription.Pull instead
-func PullWait(ctx context.Context, sub string, n int) ([]*Message, error) {
- return pull(ctx, sub, n, false)
-}
-
-func pull(ctx context.Context, sub string, n int, retImmediately bool) ([]*Message, error) {
- if n < 1 || n > batchLimit {
- return nil, fmt.Errorf("pubsub: cannot pull less than one, more than %d messages, but %d was given", batchLimit, n)
- }
- resp, err := rawService(ctx).Projects.Subscriptions.Pull(fullSubName(internal.ProjID(ctx), sub), &raw.PullRequest{
- ReturnImmediately: retImmediately,
- MaxMessages: int64(n),
- }).Do()
- if err != nil {
- return nil, err
- }
- msgs := make([]*Message, len(resp.ReceivedMessages))
- for i := 0; i < len(resp.ReceivedMessages); i++ {
- msg, err := toMessage(resp.ReceivedMessages[i])
- if err != nil {
- return nil, fmt.Errorf("pubsub: cannot decode the retrieved message at index: %d, PullResponse: %+v", i, resp.ReceivedMessages[i])
- }
- msgs[i] = msg
- }
- return msgs, nil
-}
-
-// ModifyAckDeadline modifies the acknowledgement deadline
-// for the messages retrieved from the specified subscription.
-// Deadline must not be specified to precision greater than one second.
-//
-// Deprecated: Use Subscription.Pull instead, which automatically extends ack deadlines.
-func ModifyAckDeadline(ctx context.Context, sub string, id string, deadline time.Duration) error {
- if !isSec(deadline) {
- return errors.New("pubsub: deadline must not be specified to precision greater than one second")
- }
- _, err := rawService(ctx).Projects.Subscriptions.ModifyAckDeadline(fullSubName(internal.ProjID(ctx), sub), &raw.ModifyAckDeadlineRequest{
- AckDeadlineSeconds: int64(deadline / time.Second),
- AckIds: []string{id},
- }).Do()
- return err
-}
-
-// Ack acknowledges one or more Pub/Sub messages on the
-// specified subscription.
-//
-// Deprecated: Call Message.Done on a Message returned by Iterator.Next instead.
-func Ack(ctx context.Context, sub string, id ...string) error {
- for idx, ackID := range id {
- if ackID == "" {
- return fmt.Errorf("pubsub: empty ackID detected at index %d", idx)
- }
- }
- _, err := rawService(ctx).Projects.Subscriptions.Acknowledge(fullSubName(internal.ProjID(ctx), sub), &raw.AcknowledgeRequest{
- AckIds: id,
- }).Do()
- return err
-}
-
-func isSec(dur time.Duration) bool {
- return dur%time.Second == 0
-}
-
-// Publish publishes messages to the topic's subscribers. It returns
-// message IDs upon success.
-//
-// Deprecated: Use Topic.Publish instead.
-func Publish(ctx context.Context, topic string, msgs ...*Message) ([]string, error) {
- var rawMsgs []*raw.PubsubMessage
- if len(msgs) == 0 {
- return nil, errors.New("pubsub: no messages to publish")
- }
- if len(msgs) > batchLimit {
- return nil, fmt.Errorf("pubsub: %d messages given, but maximum batch size is %d", len(msgs), batchLimit)
- }
- rawMsgs = make([]*raw.PubsubMessage, len(msgs))
- for i, msg := range msgs {
- rawMsgs[i] = &raw.PubsubMessage{
- Data: base64.StdEncoding.EncodeToString(msg.Data),
- Attributes: msg.Attributes,
- }
- }
- resp, err := rawService(ctx).Projects.Topics.Publish(fullTopicName(internal.ProjID(ctx), topic), &raw.PublishRequest{
- Messages: rawMsgs,
- }).Do()
- if err != nil {
- return nil, err
- }
- return resp.MessageIds, nil
-}
-
-// ModifyPushEndpoint modifies the URL endpoint to modify the resource
-// to handle push notifications coming from the Pub/Sub backend
-// for the specified subscription.
-//
-// Deprecated: Use Subscription.ModifyPushConfig instead.
-func ModifyPushEndpoint(ctx context.Context, sub, endpoint string) error {
- _, err := rawService(ctx).Projects.Subscriptions.ModifyPushConfig(fullSubName(internal.ProjID(ctx), sub), &raw.ModifyPushConfigRequest{
- PushConfig: &raw.PushConfig{
- PushEndpoint: endpoint,
- },
- }).Do()
- return err
-}
-
-// fullSubName returns the fully qualified name for a subscription.
-// E.g. /subscriptions/project-id/subscription-name.
-func fullSubName(proj, name string) string {
- return fmt.Sprintf("projects/%s/subscriptions/%s", proj, name)
-}
-
-func rawService(ctx context.Context) *raw.Service {
- baseAddr := func() string {
- // Environment variables for gcloud emulator:
- // https://cloud.google.com/sdk/gcloud/reference/beta/emulators/pubsub/
- if host := os.Getenv("PUBSUB_EMULATOR_HOST"); host != "" {
- return "http://" + host + "/"
- }
- return prodAddr
- }
- return internal.Service(ctx, "pubsub", func(hc *http.Client) interface{} {
- svc, _ := raw.New(hc)
- svc.BasePath = baseAddr()
- return svc
- }).(*raw.Service)
-}
-
-// fullTopicName returns the fully qualified name for a topic.
-// E.g. /topics/project-id/topic-name.
-func fullTopicName(proj, name string) string {
- return fmt.Sprintf("projects/%s/topics/%s", proj, name)
-}