dpwo36915 2015-06-01 18:35
浏览 29

在Go中使用App Engine在GCS上发布Json

I develop an app in go that locally was working perfectly with the google SDK. Now I tried to deploy it and I cannot save files on cloud storage anymore.

Here is my go code

package galileo

import (
    "encoding/json"
    "golang.org/x/net/context"
    "golang.org/x/oauth2"
    "golang.org/x/oauth2/google"
    "google.golang.org/appengine"
    "google.golang.org/appengine/file"
    "google.golang.org/appengine/urlfetch"
    "google.golang.org/cloud"
    "google.golang.org/cloud/storage"
    "io"
    "io/ioutil"
    "log"
    "net/http"
)

var bucket = "prod_agl_expt"

// saveData struct holds information needed to run the various saving functions.
type saveData struct {
    c       context.Context
    r       *http.Request       //http response
    w       http.ResponseWriter //http writer
    ctx     context.Context
    cleanUp []string // cleanUp is a list of filenames that need cleaning up at the end of the saving.
    failed  bool     // failed indicates that one or more of the saving steps failed.
}

// saveData struct holds information needed to run the various saving functions.
type loadData struct {
    c       context.Context
    r       *http.Request       //http response
    w       http.ResponseWriter //http writer
    ctx     context.Context
    cleanUp []string // cleanUp is a list of filenames that need cleaning up at the end of the saving.
    failed  bool     // failed indicates that one or more of the saving steps failed.
}

type jsonStruct struct {
    User struct {
        Gender string `json:"gender"`
        Age    string `json:"age"`
        ID     string `json:"id"`
    } `json:"user"`
    Stim map[string]struct {
        Index           int    `json:"index"`
        Word            string `json:"word"`
        WordDisplayTime int    `json:"wordDisplayTime"`
        AnswerMaxTime   int    `json:"answerMaxTime"`
        FixationTime    int    `json:"fixationTime"`
        Train           bool   `json:"train"`
        Test            bool   `json:"test"`
        Grammatical     bool   `json:"grammatical"`
        Grammar         string `json:"grammar"`
        Keyboard        bool   `json:"keyboard"`
        TestSeq         int    `json:"testSeq"`
    } `json:"viewedTrials"`
    Answers struct {
        Training []struct {
            Answer   string  `json:"ans"`
            RT       float32 `json:"RT"`
            GtAnswer string  `json:"gtAns"`
            Correct  int     `json:"correct"`
        } `json:"training"`
        Test []struct {
            Answer   string  `json:"ans"`
            RT       float32 `json:"RT"`
            GtAnswer bool    `json:"gtAns"`
            Correct  int     `json:"correct"`
        } `json:"test"`
    } `json:"answers"`
    Trials []struct {
        Trial struct {
            Index           int    `json:"index"`
            Word            string `json:"word"`
            WordDisplayTime int    `json:"wordDisplayTime"`
            AnswerMaxTime   int    `json:"answerMaxTime"`
            FixationTime    int    `json:"fixationTime"`
            Train           bool   `json:"train"`
            Test            bool   `json:"test"`
            Grammatical     bool   `json:"grammatical"`
            Grammar         string `json:"grammar"`
            Keyboard        bool   `json:"keyboard"`
            TestSeq         int    `json:"testSeq"`
        } `json:"trial"`
        Metadata struct {
            Instructions string `json:"instructions"`
            SubmitUrl    string `json:"submitUrl"`
        } `json:"metadata"`
    } `json:"shuffledTrials"`
    Debriefing []struct {
        Type             string `json:"type"`
        RadioWithTextAns string `json:"radioWithTextAns"`
        TextAns          string `json:"textAns"`
        Rating           int    `json:"rating"`
        RadioOnlyAns     string `json:"radioOnlyAns"`
    } `json:"debriefingAns"`
}

type trialStruct []struct {
    Trial struct {
        Index           int    `json:"index"`
        Word            string `json:"word"`
        WordDisplayTime int    `json:"wordDisplayTime"`
        AnswerMaxTime   int    `json:"answerMaxTime"`
        FixationTime    int    `json:"fixationTime"`
        Train           bool   `json:"train"`
        Test            bool   `json:"test"`
        Grammatical     bool   `json:"grammatical"`
        Grammar         string `json:"grammar"`
        Keyboard        bool   `json:"keyboard"`
        TestSeq         int    `json:"testSeq"`
    } `json:"trial"`
    Metadata struct {
        Instructions string `json:"instructions"`
        SubmitUrl    string `json:"submitUrl"`
    } `json:"metadata"`
}

func fromJSON(r io.Reader) (jsonStruct, error) {
    var x jsonStruct
    dec := json.NewDecoder(r)
    err := dec.Decode(&x)
    return x, err
}

func toJSON(b io.Writer, trial trialStruct) (io.Writer, error) {
    enc := json.NewEncoder(b)
    err := enc.Encode(&trial)
    return b, err
}

func init() {
    http.HandleFunc("/", handleStatic)
    http.HandleFunc("/saveUserData", handleSaveUser)
    http.HandleFunc("/loadTrials", handleloadTrials)
}

func handleStatic(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Cache-Control", "no-cache")
    http.ServeFile(w, r, "static/"+r.URL.Path)
}

// testSave is the main saving entry point that calls the GCS operations.
func handleSaveUser(w http.ResponseWriter, r *http.Request) {

    c := appengine.NewContext(r)
    if bucket == "" {
        var err error
        if bucket, err = file.DefaultBucketName(c); err != nil {
            // log.Errorf(c, "failed to get default GCS bucket name: %v", err)
            return
        }
    }
    hc := &http.Client{
        Transport: &oauth2.Transport{
            Source: google.AppEngineTokenSource(c, storage.ScopeFullControl),
            Base:   &urlfetch.Transport{Context: c},
        },
    }
    ctx := cloud.NewContext(appengine.AppID(c), hc)

    // structure to holds information needed to run the various saving functions
    d := &saveData{
        c:   c,
        r:   r,
        w:   w,
        ctx: ctx,
    }

    // retrieve data
    processedJson, trials, trainAns, testAns, stimSeq, userDetails, debriefingAns, rawJson := getJsonUserData(d.r, d.w)
    //
    d.createUserFolder(processedJson.User.ID)
    // d.saveJson(k.User.ID, "raw", z)
    d.saveJson(processedJson.User.ID, "trials", trials)
    d.saveJson(processedJson.User.ID, "train", trainAns)
    d.saveJson(processedJson.User.ID, "test", testAns)
    d.saveJson(processedJson.User.ID, "stim", stimSeq)
    d.saveJson(processedJson.User.ID, "user", userDetails)
    d.saveJson(processedJson.User.ID, "debriefing", debriefingAns)
    d.saveJson(processedJson.User.ID, "raw", rawJson)
}

// Deal with error
func (d *saveData) errorf(format string, args ...interface{}) {
    d.failed = true
}

func getJsonUserData(r *http.Request, w http.ResponseWriter) (jsonStruct, []byte, []byte, []byte, []byte, []byte, []byte, []byte) {
    defer r.Body.Close()

    procJson, err := fromJSON(r.Body)
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("initial structure: ", procJson)
    log.Printf("%+v
", procJson)
    trials, err := json.Marshal(procJson.Trials)
    if err != nil {
        log.Fatal(err)
    }
    trainAns, err := json.Marshal(procJson.Answers.Training)
    if err != nil {
        log.Fatal(err)
    }
    testAns, err := json.Marshal(procJson.Answers.Test)
    if err != nil {
        log.Fatal(err)
    }
    stimSeq, err := json.Marshal(procJson.Stim)
    if err != nil {
        log.Fatal(err)
    }
    userDetail, err := json.Marshal(procJson.User)
    if err != nil {
        log.Fatal(err)
    }
    debriefingAns, err := json.Marshal(procJson.Debriefing)
    if err != nil {
        log.Fatal(err)
    }
    rawJson, err := json.Marshal(procJson)
    if err != nil {
        log.Fatal(err)
    }
    return procJson, trials, trainAns, testAns, stimSeq, userDetail, debriefingAns, rawJson
}

func (d *saveData) createUserFolder(folderName string) {
    fName := folderName + "/"
    wc := storage.NewWriter(d.ctx, bucket, fName)
    wc.ContentType = "text/plain"
    d.cleanUp = append(d.cleanUp, fName)

    if err := wc.Close(); err != nil {
        d.errorf("createFile: unable to close bucket %q, file %q: %v", bucket, fName, err)
        return
    }

}

func (d *saveData) saveJson(folderName string, fileName string, fileContent []byte) {
    fullName := folderName + "/" + fileName
    wc := storage.NewWriter(d.ctx, bucket, fullName)
    wc.ContentType = "text/plain"
    d.cleanUp = append(d.cleanUp, fullName)
    d.createFile(fullName, fileContent)

}

func (d *saveData) createFile(fileName string, content []byte) {

    wc := storage.NewWriter(d.ctx, bucket, fileName)
    wc.ContentType = "text/plain"
    d.cleanUp = append(d.cleanUp, fileName)

    if _, err := wc.Write([]byte(content)); err != nil {
        d.errorf("createFile: unable to write data to bucket %q, file %q: %v", bucket, fileName, err)
        return
    }
    if err := wc.Close(); err != nil {
        d.errorf("createFile: unable to close bucket %q, file %q: %v", bucket, fileName, err)
        return
    }
}

func handleloadTrials(w http.ResponseWriter, r *http.Request) {
    c := appengine.NewContext(r)
    if bucket == "" {
        var err error
        if bucket, err = file.DefaultBucketName(c); err != nil {
            // log.Errorf(c, "failed to get default GCS bucket name: %v", err)
            return
        }
    }
    hc := &http.Client{
        Transport: &oauth2.Transport{
            Source: google.AppEngineTokenSource(c, storage.ScopeFullControl),
            Base:   &urlfetch.Transport{Context: c},
        },
    }
    ctx := cloud.NewContext(appengine.AppID(c), hc)

    // structure to holds information needed to run the various saving functions
    d := &saveData{
        c:   c,
        r:   r,
        w:   w,
        ctx: ctx,
    }

    userID := r.URL.Query().Get("id")
    log.Println(userID)
    trialJson := d.readFile(userID)
    w.Write(trialJson)
}

// readFile reads the named file in Google Cloud Storage.
func (d *saveData) readFile(fileName string) []byte {
    trialName := fileName + "/trials"
    rc, err := storage.NewReader(d.ctx, bucket, trialName)
    if err != nil {
        d.errorf("readFile: unable to open file from bucket %q, file %q: %v", bucket, trialName, err)

    }
    defer rc.Close()
    slurp, err := ioutil.ReadAll(rc)
    if err != nil {
        d.errorf("readFile: unable to read data from bucket %q, file %q: %v", bucket, fileName, err)
    }
    return slurp
}

The javascript code:

saveUserData : function saveUserData(data) {
  var _this = this,
      save = this.shadowRoot.querySelector('#save-data');

  save.url="http://galileoexp.appspot.com/saveUserData";
  save.body = JSON.stringify(data);
  save.go();
}

The console does not give any error when it call /saveUserData so I really do no know where the problem is, it seems like the permission are wrong but I checked them and they look good.

Any idea? thanks

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 msix packaging tool打包问题
    • ¥15 finalshell节点的搭建代码和那个端口代码教程
    • ¥15 用hfss做微带贴片阵列天线的时候分析设置有问题
    • ¥50 我撰写的python爬虫爬不了 要爬的网址有反爬机制
    • ¥15 Centos / PETSc / PETGEM
    • ¥15 centos7.9 IPv6端口telnet和端口监控问题
    • ¥120 计算机网络的新校区组网设计
    • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
    • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
    • ¥20 海浪数据 南海地区海况数据,波浪数据