How can I create cloud context.Context from appengine.Context

huangapple go评论85阅读模式
英文:

How can I create cloud context.Context from appengine.Context

问题

我无法弄清楚如何在只有appengine.Context而没有context.Context的情况下调用cloud.WithContextgoogle.DefaultClient

有两个包,一个是旧的"appengine",另一个是新的"google.golang.org/appengine"。第一个包提供了自定义的appengine.Context,而第二个包则使用来自"golang.org/x/net/context"的context.Context

整个google.golang.org/cloud只接受context.Context

我很乐意开始使用新的"google.golang.org/appengine",但我卡在了尚未移植的runtime.RunInBackground上。来自https://github.com/golang/appengine

appengine/aetestappengine/cloudsqlappengine/runtime尚未移植。

如果appengine/runtime已经移植完成,我可以这样写:

import (
    "golang.org/x/net/context"

    "google.golang.org/appengine"
    "google.golang.org/appengine/runtime"
    "google.golang.org/cloud"
    "google.golang.org/cloud/storage"
)

func handler(w http.ResponseWriter, r *http.Request) {
    c := appengine.NewContext(r)
    runtime.RunInBackground(c, func(ctx context.Context) {
        hc, _ := google.DefaultClient(ctx, storage.ScopeFullControl)
        cc := cloud.WithContext(ctx, appengine.AppID(ctx), hc)
        
   })
}

但是目前还没有"google.golang.org/appengine/runtime"。所以我有:

runtime.RunInBackground(c, func(ctx appengine.Context) {
英文:

I can't figure out how to call cloud.WithContext and google.DefaultClient if I have appengine.Context and not context.Context.

There are (old) "appengine" and (new) "google.golang.org/appengine" packages. The first one brings custom appengine.Context when second one comes with context.Context from "golang.org/x/net/context"

The whole google.golang.org/cloud expects context.Context only.

I would be happy to move to using new "google.golang.org/appengine", but I've stuck with runtime.RunInBackground that have not been ported yet. From https://github.com/golang/appengine:

> appengine/aetest, appengine/cloudsql and appengine/runtime have not been ported yet.

What I could write if appengine/runtime have been ported already:

import (
    "golang.org/x/net/context"

    "google.golang.org/appengine"
    "google.golang.org/appengine/runtime"
    "google.golang.org/cloud"
    "google.golang.org/cloud/storage"
)

func handler(w http.ResponseWriter, r *http.Request) {
    c := appengine.NewContext(r)
    runtime.RunInBackground(c, func(ctx context.Context) {
        hc, _ := google.DefaultClient(ctx, storage.ScopeFullControl)
        cc := cloud.WithContext(ctx, appengine.AppID(ctx), hc)
        …
   })
}

but there is no "google.golang.org/appengine/runtime" yet. So I have

runtime.RunInBackground(c, func(ctx appengine.Context) {

答案1

得分: 3

目前无法从(旧的)appengine.Context中获取云context.Context的方法。

托管 VM 的解决方案

一个月前,google.golang.org/appengine中添加了BackgroundContext()方法(仅适用于托管 VM)。这允许启动 goroutine 并获取云context.Context而无需传递它。

经典 Appengine 的解决方案

目前没有解决方案。

英文:

At the moment there is no way to get cloud context.Context from (old) appengine.Context.

Solution for Managed VM

A month ago BackgroundContext() method was added to google.golang.org/appengine (available for Managed VM only). This allows start goroutine and get cloud context.Context without passing it into.

Solution for classic Appengine

There is no solution at the moment.

答案2

得分: 2

做这个:

func getCloudContext(appengineContext context.Context) context.Context {
    hc := &http.Client{
        Transport: &oauth2.Transport{
            Source: google.AppEngineTokenSource(appengineContext, storage.ScopeFullControl),
            Base:   &urlfetch.Transport{Context: appengineContext},
        },
    }

    return cloud.NewContext(appengine.AppID(appengineContext), hc)
}

或者,如果通过开发服务器传递凭据不起作用,您还可以使用显式凭据:

func getCloudContext(aeCtx context.Context) (context.Context, error) {
    data, err := ioutil.ReadFile("/path/to/credentials.json")
    if err != nil {
        return nil, err
    }

    conf, err := google.JWTConfigFromJSON(
        data,
        storage.ScopeFullControl,
    )
    if err != nil {
        return nil, err
    }

    tokenSource := conf.TokenSource(aeCtx)

    hc := &http.Client{
        Transport: &oauth2.Transport{
            Source: tokenSource,
            Base:   &urlfetch.Transport{Context: aeCtx},
        },
    }

    return cloud.NewContext(appengine.AppID(aeCtx), hc), nil
}
英文:

Do this:

func getCloudContext(appengineContext context.Context) context.Context {
	hc := &http.Client{
		Transport: &oauth2.Transport{
			Source: google.AppEngineTokenSource(appengineContext, storage.ScopeFullControl),
			Base:   &urlfetch.Transport{Context: appengineContext},
		},
	}

	return cloud.NewContext(appengine.AppID(appengineContext), hc)
}

Or if passing the credentials through the dev server isn't working, you can also use explicit credentials:

func getCloudContext(aeCtx context.Context) (context.Context, error) {
	data, err := ioutil.ReadFile("/path/to/credentials.json")
	if err != nil {
		return nil, err
	}

	conf, err := google.JWTConfigFromJSON(
		data,
		storage.ScopeFullControl,
	)
	if err != nil {
		return nil, err
	}

	tokenSource := conf.TokenSource(aeCtx)

	hc := &http.Client{
		Transport: &oauth2.Transport{
			Source: tokenSource,
			Base:   &urlfetch.Transport{Context: aeCtx},
		},
	}

	return cloud.NewContext(appengine.AppID(aeCtx), hc), nil
}

答案3

得分: 1

以下是你想要的代码的翻译:

这是你可以实现你想要的方式:

import (
    "code.google.com/p/goauth2/appengine/serviceaccount"
    "golang.org/x/net/context"
    "appengine"
)

// oauth2 模块需要一个 context.Context,所以现在先使用 goauth2
func CloudContext(c appengine.Context, scopes ...string) context.Context {
    client, _ := serviceaccount.NewClient(c, scopes...)
    return cloud.WithContext(context.Background(), appengine.AppID(c), client)
}

你可以从 https://code.google.com/p/goauth2/source/browse/ 获取 goauth2 库。

英文:

Here is how you can do what you want:

import (
    "code.google.com/p/goauth2/appengine/serviceaccount"
	"golang.org/x/net/context"
	"appengine"
)

// oauth2 module requires a context.Context so use goauth2 for now
func CloudContext(c appengine.Context, scopes ...string) context.Context {
	client, _ := serviceaccount.NewClient(c, scopes...)
	return cloud.WithContext(context.Background(), appengine.AppID(c), client)
}

You can get the goauth2 library from https://code.google.com/p/goauth2/source/browse/

huangapple
  • 本文由 发表于 2015年8月23日 15:25:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/32164223.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定