Skip to content

Commit

Permalink
Remove unneeded source key properties
Browse files Browse the repository at this point in the history
  • Loading branch information
Aline Abler committed Aug 22, 2023
1 parent 3d77901 commit 3042e85
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 84 deletions.
4 changes: 2 additions & 2 deletions pkg/invoice/invoice_golden_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ func (q fakeQuerier) Query(ctx context.Context, query string, ts time.Time, _ ..
res = append(res, &model.Sample{
Metric: map[model.LabelName]model.LabelValue{
"product": model.LabelValue(k),
"category": model.LabelValue(fmt.Sprintf("%s:%s", sk.Zone, sk.Namespace)),
"tenant": model.LabelValue(sk.Tenant),
"category": model.LabelValue(fmt.Sprintf("%s:%s", sk.Part(1), sk.Part(3))),
"tenant": model.LabelValue(sk.Part(2)),
},
Value: s.Value,
})
Expand Down
4 changes: 2 additions & 2 deletions pkg/report/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,10 @@ func processSample(ctx context.Context, tx *sqlx.Tx, ts time.Time, query db.Quer

var upsertedTenant db.Tenant
err = upsertTenant(ctx, tx, &upsertedTenant, db.Tenant{
Source: skey.Tenant,
Source: skey.Tenant(),
}, ts)
if err != nil {
return fmt.Errorf("failed to upsert tenant '%s': %w", skey.Tenant, err)
return fmt.Errorf("failed to upsert tenant '%s': %w", skey.Tenant(), err)
}

var upsertedCategory db.Category
Expand Down
34 changes: 20 additions & 14 deletions pkg/sourcekey/sourcekey.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,7 @@ const elementSeparator = ":"
// SourceKey represents a source key to look up dimensions objects (currently queries and products).
// It implements the lookup logic found in https://kb.vshn.ch/appuio-cloud/references/architecture/metering-data-flow.html#_system_idea.
type SourceKey struct {
Query string
Zone string
Tenant string
Namespace string

Class string

Parts []string
parts []string
}

// Parse parses a source key in the format of "query:zone:tenant:namespace:class" or "query:zone:tenant:namespace".
Expand All @@ -29,26 +22,39 @@ func Parse(raw string) (SourceKey, error) {
if parts[len(parts)-1] == "" {
parts = parts[0 : len(parts)-1]
}
if len(parts) == 4 {
return SourceKey{parts[0], parts[1], parts[2], parts[3], "", parts}, nil
} else if len(parts) >= 5 {
return SourceKey{parts[0], parts[1], parts[2], parts[3], parts[4], parts}, nil
if len(parts) >= 4 {
return SourceKey{parts}, nil
}

return SourceKey{}, fmt.Errorf("expected key with at least 4 elements separated by `%s` got %d", elementSeparator, len(parts))
}

// Tenant returns the third element of the source key which was historically used as the tenant.
//
// Deprecated: We would like to get rid of this and read the tenant from a metric label.
func (k SourceKey) Tenant() string {
return k.parts[2]
}

// Part returns the i-th part of the source key, or an empty string if no such part exists
func (k SourceKey) Part(i int) string {
if i < len(k.parts) {
return k.parts[i]
}
return ""
}

// String returns the string representation "query:zone:tenant:namespace:class" of the key.
func (k SourceKey) String() string {
return strings.Join(k.Parts, elementSeparator)
return strings.Join(k.parts, elementSeparator)
}

// LookupKeys generates lookup keys for a dimension object in the database.
// The logic is described here: https://kb.vshn.ch/appuio-cloud/references/architecture/metering-data-flow.html#_system_idea
func (k SourceKey) LookupKeys() []string {

keys := make([]string, 0)
currentKeyBase := k.Parts
currentKeyBase := k.parts

for len(currentKeyBase) > 1 {
// For the base key of a given length l, the inner l-2 elements are to be replaced with wildcards in all possible combinations.
Expand Down
94 changes: 28 additions & 66 deletions pkg/sourcekey/sourcekey_test.go
Original file line number Diff line number Diff line change
@@ -1,85 +1,57 @@
package sourcekey_test
package sourcekey

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/appuio/appuio-cloud-reporting/pkg/sourcekey"
)

func TestParseInvalidKey(t *testing.T) {
_, err := sourcekey.Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2")
_, err := Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2")
require.Error(t, err)
}

func TestParseWithClass(t *testing.T) {
k, err := sourcekey.Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234:ssd")
func TestParseWithclass(t *testing.T) {
k, err := Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234:ssd")
require.NoError(t, err)
require.Equal(t, sourcekey.SourceKey{
Query: "appuio_cloud_storage",
Zone: "c-appuio-cloudscale-lpg-2",
Tenant: "acme-corp",
Namespace: "sparkling-sound-1234",
Class: "ssd",
Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd"},
require.Equal(t, SourceKey{
parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd"},
}, k)
}

func TestParseWithoutClass(t *testing.T) {
k, err := sourcekey.Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234")
func TestParseWithoutclass(t *testing.T) {
k, err := Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234")
require.NoError(t, err)
require.Equal(t, sourcekey.SourceKey{
Query: "appuio_cloud_storage",
Zone: "c-appuio-cloudscale-lpg-2",
Tenant: "acme-corp",
Namespace: "sparkling-sound-1234",
Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"},
require.Equal(t, SourceKey{
parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"},
}, k)
}

func TestParseWithEmptyClass(t *testing.T) {
k, err := sourcekey.Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234:")
func TestParseWithEmptyclass(t *testing.T) {
k, err := Parse("appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234:")
require.NoError(t, err)
require.Equal(t, sourcekey.SourceKey{
Query: "appuio_cloud_storage",
Zone: "c-appuio-cloudscale-lpg-2",
Tenant: "acme-corp",
Namespace: "sparkling-sound-1234",
Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"},
require.Equal(t, SourceKey{
parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"},
}, k)
}

func TestStringWithClass(t *testing.T) {
key := sourcekey.SourceKey{
Query: "appuio_cloud_storage",
Zone: "c-appuio-cloudscale-lpg-2",
Tenant: "acme-corp",
Namespace: "sparkling-sound-1234",
Class: "ssd",
Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd"},
func TestStringWithclass(t *testing.T) {
key := SourceKey{
parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd"},
}
require.Equal(t, "appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234:ssd", key.String())
}

func TestStringWithoutClass(t *testing.T) {
key := sourcekey.SourceKey{
Query: "appuio_cloud_storage",
Zone: "c-appuio-cloudscale-lpg-2",
Tenant: "acme-corp",
Namespace: "sparkling-sound-1234",
Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"},
func TestStringWithoutclass(t *testing.T) {
key := SourceKey{
parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"},
}
require.Equal(t, "appuio_cloud_storage:c-appuio-cloudscale-lpg-2:acme-corp:sparkling-sound-1234", key.String())
}

func TestGenerateSourceKeysWithoutClass(t *testing.T) {
keys := sourcekey.SourceKey{
Query: "appuio_cloud_storage",
Zone: "c-appuio-cloudscale-lpg-2",
Tenant: "acme-corp",
Namespace: "sparkling-sound-1234",
Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"},
func TestGenerateSourceKeysWithoutclass(t *testing.T) {
keys := SourceKey{
parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234"},
}.LookupKeys()

require.Equal(t, []string{
Expand All @@ -94,14 +66,9 @@ func TestGenerateSourceKeysWithoutClass(t *testing.T) {
}, keys)
}

func TestGenerateSourceKeysWithClass(t *testing.T) {
keys := sourcekey.SourceKey{
Query: "appuio_cloud_storage",
Zone: "c-appuio-cloudscale-lpg-2",
Tenant: "acme-corp",
Namespace: "sparkling-sound-1234",
Class: "ssd",
Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd"},
func TestGenerateSourceKeysWithclass(t *testing.T) {
keys := SourceKey{
parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd"},
}.LookupKeys()

require.Equal(t, []string{
Expand All @@ -125,13 +92,8 @@ func TestGenerateSourceKeysWithClass(t *testing.T) {
}

func TestGenerateSourceKeysWithSixElements(t *testing.T) {
keys := sourcekey.SourceKey{
Query: "appuio_cloud_storage",
Zone: "c-appuio-cloudscale-lpg-2",
Tenant: "acme-corp",
Namespace: "sparkling-sound-1234",
Class: "ssd",
Parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd", "exoscale"},
keys := SourceKey{
parts: []string{"appuio_cloud_storage", "c-appuio-cloudscale-lpg-2", "acme-corp", "sparkling-sound-1234", "ssd", "exoscale"},
}.LookupKeys()

require.Equal(t, []string{
Expand Down

0 comments on commit 3042e85

Please sign in to comment.