in wstl1/mapping_engine/cloudfunction/cloudfunction.go [57:115]
func FromCloudFunction(cf *httppb.CloudFunction) (types.Projector, error) {
if err := validateCloudFunction(cf); err != nil {
return nil, fmt.Errorf("invalid Google cloud function definition: %v", err)
}
return func(metaArgs []jsonutil.JSONMetaNode, pctx *types.Context) (jsonutil.JSONToken, error) {
errLocation := errs.FnLocationf("Cloud Function Preamble %q", cf.Name)
args := make([]jsonutil.JSONToken, len(metaArgs))
for i, metaArg := range metaArgs {
node, err := jsonutil.NodeToToken(metaArg)
if err != nil {
return nil, errs.Wrap(errLocation, fmt.Errorf("error converting args: %v", err))
}
args[i] = node
}
var body []byte
var err error
if len(args) == 1 {
body, err = json.Marshal(args[0])
} else {
body, err = json.Marshal(args)
}
if err != nil {
return nil, errs.Wrap(errLocation, fmt.Errorf("error marshaling arguments into a JSON object: %v", err))
}
errLocation = errs.FnLocationf("Cloud Function %q", cf.Name)
resp, err := http.Post(cf.RequestUrl, "application/json", bytes.NewBuffer(body))
if err != nil {
return nil, errs.Wrap(errLocation, fmt.Errorf("cloud function request failed due to: %v", err))
}
if resp.StatusCode != http.StatusOK {
message, _ := ioutil.ReadAll(resp.Body)
return nil, errs.Wrap(errLocation, fmt.Errorf("error http response status code: %v, error message: %s", resp.Status, message))
}
defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, errs.Wrap(errLocation, fmt.Errorf("error reading http response body: %v", err))
}
if len(bytes) == 0 {
return nil, errs.Wrap(errLocation, fmt.Errorf("error empty http response body"))
}
val, err := jsonutil.UnmarshalJSON(json.RawMessage(bytes))
if err != nil {
return nil, errs.Wrap(errLocation, fmt.Errorf("error unmarshal http response body into JSONToken: %v", err))
}
return val, nil
}, nil
}