feat: Integrate with Report v2 in the go app for the Example API.

For more information, see https://cloud.google.com/service-infrastructure/docs/service-control/reference/rest/v2/services/report.

PiperOrigin-RevId: 343146007
This commit is contained in:
Google APIs 2020-11-18 13:36:20 -08:00 committed by Copybara-Service
parent 2cda8d285b
commit f1e0ce4dbc
1 changed files with 85 additions and 16 deletions

View File

@ -19,15 +19,12 @@ import (
// Check calls Service Control API v2 for admission control.
// Name specifies the target resource name. Permission specifies
// the required permission on the target resource.
func check(w http.ResponseWriter, r *http.Request, name string, permission string) (string, error) {
client, err := servicecontrol.NewService(r.Context())
if err != nil {
return "", err
}
// the required permission on the target resource. Received
// specifies the timestamp when the request is received.
func check(w http.ResponseWriter, r *http.Request, name string, permission string, received time.Time, client *servicecontrol.Service) (string, error) {
// Construct CheckRequest from the incoming HTTP request.
// The code assumes the incoming request processed by App Engine ingress.
checkRequest := &servicecontrol.CheckRequest{
req := &servicecontrol.CheckRequest{
ServiceConfigId: "latest",
Attributes: &servicecontrol.AttributeContext{
Origin: &servicecontrol.Peer{
@ -41,7 +38,7 @@ func check(w http.ResponseWriter, r *http.Request, name string, permission strin
},
Request: &servicecontrol.Request{
Id: r.Header.Get("x-appengine-request-log-id"),
Time: time.Now().UTC().Format(time.RFC3339),
Time: received.UTC().Format(time.RFC3339),
Method: r.Method,
Scheme: r.Header.Get("x-forwarded-proto"),
Host: r.Host,
@ -53,6 +50,9 @@ func check(w http.ResponseWriter, r *http.Request, name string, permission strin
"referer": r.Header.Get("referer"),
},
},
Resource: &servicecontrol.Resource{
Name: name,
},
},
Resources: []*servicecontrol.ResourceInfo{
{
@ -62,18 +62,64 @@ func check(w http.ResponseWriter, r *http.Request, name string, permission strin
},
},
}
response, err := client.Services.Check("endpointsapis.appspot.com", checkRequest).Do()
resp, err := client.Services.Check("endpointsapis.appspot.com", req).Do()
if err != nil {
return "", err
}
responseJSON, err := response.MarshalJSON()
json, err := resp.MarshalJSON()
if err != nil {
return "", err
}
return string(responseJSON), nil
return string(json), nil
}
func admission(w http.ResponseWriter, r *http.Request) (string, error) {
// Report calls Service Control API v2 for telemetry reporting.
// Name specifies the target resource name. ResponseCode specifies
// the response code returned to user. Received specifies the
// timestamp when the request is received.
func report(w http.ResponseWriter, r *http.Request, name string, responseCode int64, received time.Time, client *servicecontrol.Service) (string, error) {
// Construct ReportRequest from the incoming HTTP request.
// The code assumes the incoming request processed by App Engine ingress.
req := &servicecontrol.ReportRequest{
ServiceConfigId: "latest",
Operations: []*servicecontrol.AttributeContext{
{
Api: &servicecontrol.Api{
Service: "endpointsapis.appspot.com",
Operation: "google.example.endpointsapis.v1.Workspaces.GetWorkspace",
Version: "v1",
Protocol: r.Header.Get("x-forwarded-proto"),
},
Request: &servicecontrol.Request{
Size: r.ContentLength,
Time: received.UTC().Format(time.RFC3339),
},
Response: &servicecontrol.Response{
Time: time.Now().UTC().Format(time.RFC3339),
Code: responseCode,
Headers: map[string]string{
"x-backend-latency": "0.007",
},
},
Destination: &servicecontrol.Peer{
RegionCode: "us-central1",
},
Resource: &servicecontrol.Resource{
Name: name,
},
},
},
}
_, err := client.Services.Report("endpointsapis.appspot.com", req).Do()
if err != nil {
return "", err
}
return "{}", nil
}
// Parse processes the request path and extract the resource name and
// permissions.
func parse(r *http.Request) (string, string, error) {
// Split the request path.
segments := strings.Split(r.URL.Path, "/")
@ -81,25 +127,45 @@ func admission(w http.ResponseWriter, r *http.Request) (string, error) {
// "/v1/projects/*/locations/*/workspaces". They correspond to the
// GetWorkspace() and ListWorkspaces() methods defined in ../v1/workspace.proto.
if segments[0] != "" || segments[1] != "v1" || segments[2] != "projects" || segments[4] != "locations" || segments[6] != "workspaces" || len(segments) > 8 {
return "", errors.New("Resource '" + r.URL.Path + "' not found.")
return "", "", errors.New("Resource '" + r.URL.Path + "' not found.")
}
// Skip prefix "/v1/".
resource := r.URL.Path[4:]
permission := "endpointsapis.appspot.com/workspaces.list"
if len(segments) == 8 {
permission = "endpointsapis.appspot.com/workspaces.get"
}
return check(w, r, resource, permission)
return resource, permission, nil
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
// Perform admission control.
result, err := admission(w, r)
received := time.Now()
// Create a client for Service Control API v2.
client, err := servicecontrol.NewService(r.Context())
if err != nil {
fmt.Fprintln(w, "Error:")
fmt.Fprintln(w, err.Error())
return
}
resource, permission, err := parse(r)
if err != nil {
fmt.Fprintln(w, "Error:")
fmt.Fprintln(w, err.Error())
return
}
// Perform admission control.
result, err := check(w, r, resource, permission, received, client)
var responseCode int64 = 200
// Print the admission control result.
if err != nil {
fmt.Fprintln(w, "Error:")
fmt.Fprintln(w, err.Error())
responseCode = 403
} else {
fmt.Fprintln(w, "CheckResponse:")
fmt.Fprintln(w, result)
@ -116,6 +182,9 @@ func indexHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "%v: %v\n", key, value)
}
}
// Perform telemetry report.
report(w, r, resource, responseCode, received, client)
}
func main() {