Skip to content

Commit

Permalink
chore(storage): parse out project number if available (#6671)
Browse files Browse the repository at this point in the history
The JSON API has a dedicated `ProjectNumber uint64` field used to populate the same field on `BucketAttrs`. The gRPC API has a `string project` field that can contain either a project *number* or a project *identifier* (alphanumeric). Parse out the *project number* if it is present in the returned `Bucket`, otherwise leave it as `0`.
  • Loading branch information
noahdietz committed Sep 20, 2022
1 parent feb7d7d commit 17cceeb
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
1 change: 1 addition & 0 deletions storage/bucket.go
Expand Up @@ -775,6 +775,7 @@ func newBucketFromProto(b *storagepb.Bucket) *BucketAttrs {
LocationType: b.GetLocationType(),
RPO: toRPOFromProto(b),
CustomPlacementConfig: customPlacementFromProto(b.GetCustomPlacementConfig()),
ProjectNumber: parseProjectNumber(b.GetProject()), // this can return 0 the project resource name is ID based
}
}

Expand Down
19 changes: 19 additions & 0 deletions storage/storage.go
Expand Up @@ -33,6 +33,7 @@ import (
"reflect"
"regexp"
"sort"
"strconv"
"strings"
"time"
"unicode/utf8"
Expand Down Expand Up @@ -2002,6 +2003,24 @@ func parseBucketName(b string) string {
return b[sep+1:]
}

// parseProjectNumber consume the given resource name and parses out the project
// number if one is present i.e. it is not a project ID.
func parseProjectNumber(r string) uint64 {
projectID := regexp.MustCompile(`projects\/([0-9]+)\/?`)
if matches := projectID.FindStringSubmatch(r); len(matches) > 0 {
// Capture group follows the matched segment. For example:
// input: projects/123/bars/456
// output: [projects/123/, 123]
number, err := strconv.ParseUint(matches[1], 10, 64)
if err != nil {
return 0
}
return number
}

return 0
}

// toProjectResource accepts a project ID and formats it as a Project resource
// name.
func toProjectResource(project string) string {
Expand Down
18 changes: 18 additions & 0 deletions storage/storage_test.go
Expand Up @@ -2341,6 +2341,24 @@ func TestSignedURLOptionsClone(t *testing.T) {
}
}

func TestParseProjectNumber(t *testing.T) {
for _, tst := range []struct {
input string
want uint64
}{
{"projects/123", 123},
{"projects/123/foos/456", 123},
{"projects/abc-123/foos/456", 0},
{"projects/abc-123", 0},
{"projects/abc", 0},
{"projects/abc/foos", 0},
} {
if got := parseProjectNumber(tst.input); got != tst.want {
t.Errorf("For %q: got %v, expected %v", tst.input, got, tst.want)
}
}
}

// isZeroValue reports whether v is the zero value for its type
// It errors if the argument is unknown
func isZeroValue(v reflect.Value) (bool, error) {
Expand Down

0 comments on commit 17cceeb

Please sign in to comment.