Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PoC: ScopeMetadata and PrefixMetadata #358

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 0 additions & 108 deletions connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ package dosa

import (
"context"
"fmt"
"sort"
"strings"
"time"
)

Expand Down Expand Up @@ -77,56 +74,6 @@ type EntityInfo struct {
TTL *time.Duration
}

// StringSet is a set of strings.
type StringSet map[string]struct{}

// ScopeMetadata is metadata about a scope. (JSON tags to support MD setting CLI tools.) The scope
// may be qualified by a prefix, as in "production.vsoffers".
type ScopeMetadata struct {
Entity `dosa:"primaryKey=(Name)" json:"-"`
Name string `json:"name"`
Owner string `json:"owner"` // Owning group name (or the same as Creator)
Type int32 `json:"type"` // Production, Staging, or Development
Flags int64 `json:"flags"`
Version int32 `json:"version"`
PrefixStr string `json:"prefix_str,omitempty"` // With ":" separators
Cluster string `json:"cluster,omitempty"` // Host DB cluster
Creator string `json:"creator"`
CreatedOn time.Time `json:"created_on"`
ExpiresOn *time.Time `json:"expires_on,omitempty"`
ExtendCount int32 `json:"extend_count,omitempty"`
NotifyCount int32 `json:"notify_count,omitempty"`
ReadMaxRPS int32 `json:"read_max_rps"`
WriteMaxRPS int32 `json:"write_max_rps"`
// This is for convenience only, not stored in the DB:
Prefixes StringSet `dosa:"-" json:"-"`
}

// MetadataSchemaVersion is the version of the schema of the scope metadata
const MetadataSchemaVersion = 1

// ScopeType is the type of a scope
type ScopeType int32

// Scope types
const (
// Development scope (also the default, so should be 0)
Development ScopeType = iota
// Staging doesn't really exist yet, but may in the future
Staging
// Production scope
Production
)

// ScopeFlagType is a set of scope flags
type ScopeFlagType int64

// Scope flags (remember to update ScopeFlagType.String)
const (
// AccessFromProd means access is allowed from production (only relevant for Dev scopes)
AccessFromProd ScopeFlagType = 1 << iota
)

// FieldValue holds a field value. It's just a marker.
type FieldValue interface{}

Expand Down Expand Up @@ -206,58 +153,3 @@ type Connector interface {
// Shutdown finishes the connector to do clean up work
Shutdown() error
}

func (t ScopeType) String() string {
switch t {
case Production:
return "production"
case Staging:
return "staging"
case Development:
return "development"
}
return fmt.Sprintf("unknown scope type %d", t)
}

func (md *ScopeMetadata) String() string {
s := fmt.Sprintf("<Scope %s (%s): owner=%s, creator=%s, created=%v", md.Name, ScopeType(md.Type),
md.Owner, md.Creator, md.CreatedOn)
if md.ExpiresOn != nil {
s += fmt.Sprintf(", expires=%v", *md.ExpiresOn)
}
if len(md.Prefixes) > 0 {
s += fmt.Sprintf(", prefixes=%s", md.Prefixes)
}
if len(md.PrefixStr) > 0 {
s += fmt.Sprintf(", prefixes=%v", md.PrefixStr)
}
if len(md.Cluster) > 0 {
s += fmt.Sprintf(", cluster=%v", md.Cluster)
}
if md.ExtendCount > 0 {
s += fmt.Sprintf(", extended=%d", md.ExtendCount)
}
if md.NotifyCount > 0 {
s += fmt.Sprintf(", notified=%d", md.ExtendCount)
}
return s + ">"
}

func (s StringSet) String() string {
ss := make([]string, len(s))
i := 0
for k := range s {
ss[i] = k
i++
}
sort.Strings(ss)
return "{" + strings.Join(ss, ", ") + "}"
}

func (f ScopeFlagType) String() string {
fs := make([]string, 1)
if f&AccessFromProd != 0 {
fs = append(fs, "AccessFromProd")
}
return "{" + strings.Join(fs, ", ") + "}"
}
12 changes: 8 additions & 4 deletions finder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"fmt"
"io/ioutil"
"os"
"sort"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -76,6 +77,7 @@ func TestParser(t *testing.T) {
"multipleindexes": &MultipleIndexes{},
"complexindexes": &ComplexIndexes{},
"scopemetadata": &ScopeMetadata{},
"prefixmetadata": &PrefixMetadata{},
}
entitiesExcludedForTest := map[string]interface{}{
"clienttestentity1": struct{}{}, // skip, see https://jira.uberinternal.com/browse/DOSA-788
Expand Down Expand Up @@ -104,11 +106,13 @@ func TestParser(t *testing.T) {

func TestExclusion(t *testing.T) {
entities, errs, err := findEntities([]string{"."}, []string{"*_test.go"})
// We expect to find only ScopeMetadata
assert.Equal(t, 1, len(entities))
assert.Equal(t, "ScopeMetadata", entities[0].StructName)
assert.Equal(t, 0, len(errs))
assert.Nil(t, err)
assert.Equal(t, 0, len(errs))
// We expect to find only ScopeMetadata and Prefixmetadata
assert.Equal(t, 2, len(entities))
enames := []string{entities[0].StructName, entities[1].StructName}
sort.Strings(enames)
assert.Equal(t, []string{"PrefixMetadata", "ScopeMetadata"}, enames)
}

func TestFindEntitiesInOtherPkg(t *testing.T) {
Expand Down
102 changes: 102 additions & 0 deletions metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright (c) 2018 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package dosa

import (
"sort"
"strings"
"time"
)

// Metadata objects are abstracted by an interface that defines getters and setters. Getters are
// named Get*() because we can't have fields and methods with the same name (and all fields must
// be exported in a DOSA entity).

// Metadata is an interface abstracting both ScopeMetadata and PrefixMetadata.
type Metadata interface {
// GetName is the name of the object.
GetName() string
// GetOwner is the owner of the object.
GetOwner() string
// GetType is the type of the object.
GetType() int32
// GetFlags is the flags of the object.
GetFlags() int64
// GetVersion is the version of the object.
GetVersion() int32
// GetCluster is the cluster name of the object.
GetCluster() string
// GetCreator is the creator of the object.
GetCreator() string
// GetCreatedOn is the create timestamp of the object.
GetCreatedOn() time.Time
// GetExpiresOn is the expiration timestamp of the object.
GetExpiresOn() time.Time
// GetExtendCount is the extend count of the object.
GetExtendCount() int32
// GetNotifyCount is the notify count of the object.
GetNotifyCount() int32
// GetReadMaxRPS is the max read rate for the object.
GetReadMaxRPS() int32
// GetWriteMaxRPS is the max write rate for the object.
GetWriteMaxRPS() int32

// SetName sets the name of the object.
SetName(string)
// SetOwner sets the owner of the object.
SetOwner(string)
// SetType sets the type of the object.
SetType(int32)
// SetFlags sets the flags of the object.
SetFlags(int64)
// SetVersion sets the version of the object.
SetVersion(int32)
// SetCluster sets the cluster name of the object.
SetCluster(string)
// SetCreator sets the creator of the object.
SetCreator(string)
// SetCreatedOn sets the create timestamp of the object.
SetCreatedOn(time.Time)
// SetExpiresOn sets the expiration timestamp of the object.
SetExpiresOn(time.Time)
// SetExtendCount sets the extend count of the object.
SetExtendCount(int32)
// SetNotifyCount sets the notify count of the object.
SetNotifyCount(int32)
// SetReadMaxRPS sets the max read rate for the object.
SetReadMaxRPS(int32)
// SetWriteMaxRPS sets the max write rate for the object.
SetWriteMaxRPS(int32)
}

// StringSet is a set of strings.
type StringSet map[string]struct{}

func (s StringSet) String() string {
ss := make([]string, len(s))
i := 0
for k := range s {
ss[i] = k
i++
}
sort.Strings(ss)
return "{" + strings.Join(ss, ", ") + "}"
}
Loading