feat(influxdb): bucket created and updated time

pull/13954/head
Kelvin Wang 2019-05-17 11:12:09 -04:00
parent d31be2a6f5
commit 57ceb9e275
16 changed files with 119 additions and 4 deletions

View File

@ -351,6 +351,8 @@ func (c *Client) CreateBucket(ctx context.Context, b *platform.Bucket) error {
}
b.ID = c.IDGenerator.ID()
b.CreatedAt = c.Now()
b.UpdatedAt = c.Now()
if err = c.appendBucketEventToLog(ctx, tx, b.ID, bucketCreatedEvent); err != nil {
return &platform.Error{
@ -545,6 +547,8 @@ func (c *Client) updateBucket(ctx context.Context, tx *bolt.Tx, id platform.ID,
b.Name = *upd.Name
}
b.UpdatedAt = c.Now()
if err := c.appendBucketEventToLog(ctx, tx, b.ID, bucketUpdatedEvent); err != nil {
return nil, err
}

View File

@ -15,6 +15,10 @@ func initBucketService(f platformtesting.BucketFields, t *testing.T) (platform.B
t.Fatalf("failed to create new bolt client: %v", err)
}
c.IDGenerator = f.IDGenerator
c.TimeGenerator = f.TimeGenerator
if f.TimeGenerator == nil {
c.TimeGenerator = platform.RealTimeGenerator{}
}
ctx := context.TODO()
for _, o := range f.Organizations {
if err := c.PutOrganization(ctx, o); err != nil {

View File

@ -15,6 +15,10 @@ func initOnboardingService(f platformtesting.OnboardingFields, t *testing.T) (pl
}
c.IDGenerator = f.IDGenerator
c.TokenGenerator = f.TokenGenerator
c.TimeGenerator = f.TimeGenerator
if c.TimeGenerator == nil {
c.TimeGenerator = platform.RealTimeGenerator{}
}
ctx := context.TODO()
if err = c.PutOnboardingStatus(ctx, !f.IsOnboarding); err != nil {
t.Fatalf("failed to set new onboarding finished: %v", err)

View File

@ -26,6 +26,7 @@ type Bucket struct {
Description string `json:"description"`
RetentionPolicyName string `json:"rp,omitempty"` // This to support v1 sources
RetentionPeriod time.Duration `json:"retentionPeriod"`
CRUDLog
}
// ops for buckets error and buckets op logs.

View File

@ -132,6 +132,7 @@ type bucket struct {
Name string `json:"name"`
RetentionPolicyName string `json:"rp,omitempty"` // This to support v1 sources
RetentionRules []retentionRule `json:"retentionRules"`
influxdb.CRUDLog
}
// retentionRule is the retention rule action for a bucket.
@ -165,6 +166,7 @@ func (b *bucket) toInfluxDB() (*influxdb.Bucket, error) {
Name: b.Name,
RetentionPolicyName: b.RetentionPolicyName,
RetentionPeriod: d,
CRUDLog: b.CRUDLog,
}, nil
}
@ -189,6 +191,7 @@ func newBucket(pb *influxdb.Bucket) *bucket {
Description: pb.Description,
RetentionPolicyName: pb.RetentionPolicyName,
RetentionRules: rules,
CRUDLog: pb.CRUDLog,
}
}

View File

@ -114,6 +114,8 @@ func TestService_handleGetBuckets(t *testing.T) {
"members": "/api/v2/buckets/0b501e7e557ab1ed/members",
"write": "/api/v2/write?org=50f7ba1150f7ba11&bucket=0b501e7e557ab1ed"
},
"createdAt": "0001-01-01T00:00:00Z",
"updatedAt": "0001-01-01T00:00:00Z",
"id": "0b501e7e557ab1ed",
"orgID": "50f7ba1150f7ba11",
"name": "hello",
@ -138,6 +140,8 @@ func TestService_handleGetBuckets(t *testing.T) {
"owners": "/api/v2/buckets/c0175f0077a77005/owners",
"write": "/api/v2/write?org=7e55e118dbabb1ed&bucket=c0175f0077a77005"
},
"createdAt": "0001-01-01T00:00:00Z",
"updatedAt": "0001-01-01T00:00:00Z",
"id": "c0175f0077a77005",
"orgID": "7e55e118dbabb1ed",
"name": "example",
@ -278,6 +282,8 @@ func TestService_handleGetBucket(t *testing.T) {
"owners": "/api/v2/buckets/020f755c3c082000/owners",
"write": "/api/v2/write?org=020f755c3c082000&bucket=020f755c3c082000"
},
"createdAt": "0001-01-01T00:00:00Z",
"updatedAt": "0001-01-01T00:00:00Z",
"id": "020f755c3c082000",
"orgID": "020f755c3c082000",
"name": "hello",
@ -407,6 +413,8 @@ func TestService_handlePostBucket(t *testing.T) {
"owners": "/api/v2/buckets/020f755c3c082000/owners",
"write": "/api/v2/write?org=6f626f7274697320&bucket=020f755c3c082000"
},
"createdAt": "0001-01-01T00:00:00Z",
"updatedAt": "0001-01-01T00:00:00Z",
"id": "020f755c3c082000",
"orgID": "6f626f7274697320",
"name": "hello",
@ -626,6 +634,8 @@ func TestService_handlePatchBucket(t *testing.T) {
"owners": "/api/v2/buckets/020f755c3c082000/owners",
"write": "/api/v2/write?org=020f755c3c082000&bucket=020f755c3c082000"
},
"createdAt": "0001-01-01T00:00:00Z",
"updatedAt": "0001-01-01T00:00:00Z",
"id": "020f755c3c082000",
"orgID": "020f755c3c082000",
"name": "example",
@ -702,6 +712,8 @@ func TestService_handlePatchBucket(t *testing.T) {
"owners": "/api/v2/buckets/020f755c3c082000/owners",
"write": "/api/v2/write?org=020f755c3c082000&bucket=020f755c3c082000"
},
"createdAt": "0001-01-01T00:00:00Z",
"updatedAt": "0001-01-01T00:00:00Z",
"id": "020f755c3c082000",
"orgID": "020f755c3c082000",
"name": "bucket with no retention",
@ -759,6 +771,8 @@ func TestService_handlePatchBucket(t *testing.T) {
"owners": "/api/v2/buckets/020f755c3c082000/owners",
"write": "/api/v2/write?org=020f755c3c082000&bucket=020f755c3c082000"
},
"createdAt": "0001-01-01T00:00:00Z",
"updatedAt": "0001-01-01T00:00:00Z",
"id": "020f755c3c082000",
"orgID": "020f755c3c082000",
"name": "b1",
@ -1053,6 +1067,10 @@ func TestService_handlePostBucketOwner(t *testing.T) {
func initBucketService(f platformtesting.BucketFields, t *testing.T) (platform.BucketService, string, func()) {
svc := inmem.NewService()
svc.IDGenerator = f.IDGenerator
svc.TimeGenerator = f.TimeGenerator
if f.TimeGenerator == nil {
svc.TimeGenerator = platform.RealTimeGenerator{}
}
ctx := context.Background()
for _, o := range f.Organizations {

View File

@ -26,6 +26,10 @@ func initOnboardingService(f platformtesting.OnboardingFields, t *testing.T) (pl
svc := inmem.NewService()
svc.IDGenerator = f.IDGenerator
svc.TokenGenerator = f.TokenGenerator
if f.TimeGenerator == nil {
svc.TimeGenerator = platform.RealTimeGenerator{}
}
svc.TimeGenerator = f.TimeGenerator
ctx := context.Background()
if err := svc.PutOnboardingStatus(ctx, !f.IsOnboarding); err != nil {

View File

@ -5590,6 +5590,14 @@ components:
type: string
rp:
type: string
createdAt:
type: string
format: date-time
readOnly: true
updatedAt:
type: string
format: date-time
readOnly: true
retentionRules:
type: array
description: rules to expire or retain data. No rules means data never expires.

View File

@ -242,6 +242,8 @@ func (s *Service) CreateBucket(ctx context.Context, b *platform.Bucket) error {
}
}
b.ID = s.IDGenerator.ID()
b.CreatedAt = s.Now()
b.UpdatedAt = s.Now()
return s.PutBucket(ctx, b)
}
@ -284,6 +286,7 @@ func (s *Service) UpdateBucket(ctx context.Context, id platform.ID, upd platform
}
}
b.UpdatedAt = s.Now()
s.bucketKV.Store(b.ID.String(), b)
return b, nil

View File

@ -11,6 +11,10 @@ import (
func initBucketService(f platformtesting.BucketFields, t *testing.T) (platform.BucketService, string, func()) {
s := NewService()
s.IDGenerator = f.IDGenerator
s.TimeGenerator = f.TimeGenerator
if f.TimeGenerator == nil {
s.TimeGenerator = platform.RealTimeGenerator{}
}
ctx := context.Background()
for _, o := range f.Organizations {
if err := s.PutOrganization(ctx, o); err != nil {

View File

@ -12,6 +12,10 @@ func initOnboardingService(f platformtesting.OnboardingFields, t *testing.T) (pl
s := NewService()
s.IDGenerator = f.IDGenerator
s.TokenGenerator = f.TokenGenerator
s.TimeGenerator = f.TimeGenerator
if f.TimeGenerator == nil {
s.TimeGenerator = platform.RealTimeGenerator{}
}
ctx := context.TODO()
if err := s.PutOnboardingStatus(ctx, !f.IsOnboarding); err != nil {
t.Fatalf("failed to set new onboarding finished: %v", err)

View File

@ -383,6 +383,8 @@ func (s *Service) createBucket(ctx context.Context, tx Tx, b *influxdb.Bucket) e
}
b.ID = s.IDGenerator.ID()
b.CreatedAt = s.Now()
b.UpdatedAt = s.Now()
if err := s.appendBucketEventToLog(ctx, tx, b.ID, bucketCreatedEvent); err != nil {
return &influxdb.Error{
@ -616,6 +618,8 @@ func (s *Service) updateBucket(ctx context.Context, tx Tx, id influxdb.ID, upd i
b.Name = *upd.Name
}
b.UpdatedAt = s.Now()
if err := s.appendBucketEventToLog(ctx, tx, b.ID, bucketUpdatedEvent); err != nil {
return nil, err
}

View File

@ -46,6 +46,10 @@ func initInmemBucketService(f influxdbtesting.BucketFields, t *testing.T) (influ
func initBucketService(s kv.Store, f influxdbtesting.BucketFields, t *testing.T) (influxdb.BucketService, string, func()) {
svc := kv.NewService(s)
svc.IDGenerator = f.IDGenerator
svc.TimeGenerator = f.TimeGenerator
if f.TimeGenerator == nil {
svc.TimeGenerator = influxdb.RealTimeGenerator{}
}
ctx := context.Background()
if err := svc.Initialize(ctx); err != nil {

View File

@ -47,6 +47,11 @@ func initOnboardingService(s kv.Store, f influxdbtesting.OnboardingFields, t *te
svc := kv.NewService(s)
svc.IDGenerator = f.IDGenerator
svc.TokenGenerator = f.TokenGenerator
svc.TimeGenerator = f.TimeGenerator
if f.TimeGenerator == nil {
svc.TimeGenerator = influxdb.RealTimeGenerator{}
}
ctx := context.Background()
if err := svc.Initialize(ctx); err != nil {
t.Fatalf("unable to initialize kv store: %v", err)

View File

@ -35,6 +35,7 @@ var bucketCmpOptions = cmp.Options{
// BucketFields will include the IDGenerator, and buckets
type BucketFields struct {
IDGenerator platform.IDGenerator
TimeGenerator platform.TimeGenerator
Buckets []*platform.Bucket
Organizations []*platform.Organization
}
@ -108,6 +109,7 @@ func CreateBucket(
name: "create buckets with empty set",
fields: BucketFields{
IDGenerator: mock.NewIDGenerator(bucketOneID, t),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Buckets: []*platform.Bucket{},
Organizations: []*platform.Organization{
{
@ -130,6 +132,10 @@ func CreateBucket(
ID: MustIDBase16(bucketOneID),
OrgID: MustIDBase16(orgOneID),
Description: "desc1",
CRUDLog: platform.CRUDLog{
CreatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},
@ -142,6 +148,7 @@ func CreateBucket(
return MustIDBase16(bucketTwoID)
},
},
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Buckets: []*platform.Bucket{
{
ID: MustIDBase16(bucketOneID),
@ -177,6 +184,10 @@ func CreateBucket(
ID: MustIDBase16(bucketTwoID),
Name: "bucket2",
OrgID: MustIDBase16(orgTwoID),
CRUDLog: platform.CRUDLog{
CreatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},
@ -189,6 +200,7 @@ func CreateBucket(
return MustIDBase16(bucketTwoID)
},
},
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Buckets: []*platform.Bucket{
{
ID: MustIDBase16(bucketOneID),
@ -236,6 +248,7 @@ func CreateBucket(
return MustIDBase16(bucketTwoID)
},
},
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*platform.Organization{
{
Name: "theorg",
@ -271,6 +284,10 @@ func CreateBucket(
ID: MustIDBase16(bucketTwoID),
Name: "bucket1",
OrgID: MustIDBase16(orgTwoID),
CRUDLog: platform.CRUDLog{
CreatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},
@ -279,6 +296,7 @@ func CreateBucket(
name: "create bucket with orgID not exist",
fields: BucketFields{
IDGenerator: mock.NewIDGenerator(bucketOneID, t),
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Buckets: []*platform.Bucket{},
Organizations: []*platform.Organization{},
},
@ -1012,6 +1030,7 @@ func UpdateBucket(
{
name: "update name",
fields: BucketFields{
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*platform.Organization{
{
Name: "theorg",
@ -1040,12 +1059,16 @@ func UpdateBucket(
ID: MustIDBase16(bucketOneID),
OrgID: MustIDBase16(orgOneID),
Name: "changed",
CRUDLog: platform.CRUDLog{
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},
{
name: "update name unique",
fields: BucketFields{
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*platform.Organization{
{
Name: "theorg",
@ -1079,6 +1102,7 @@ func UpdateBucket(
{
name: "update retention",
fields: BucketFields{
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*platform.Organization{
{
Name: "theorg",
@ -1108,12 +1132,16 @@ func UpdateBucket(
OrgID: MustIDBase16(orgOneID),
Name: "bucket1",
RetentionPeriod: 100 * time.Minute,
CRUDLog: platform.CRUDLog{
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},
{
name: "update description",
fields: BucketFields{
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*platform.Organization{
{
Name: "theorg",
@ -1143,12 +1171,16 @@ func UpdateBucket(
OrgID: MustIDBase16(orgOneID),
Name: "bucket1",
Description: "desc1",
CRUDLog: platform.CRUDLog{
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},
{
name: "update retention and name",
fields: BucketFields{
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*platform.Organization{
{
Name: "theorg",
@ -1179,12 +1211,16 @@ func UpdateBucket(
OrgID: MustIDBase16(orgOneID),
Name: "changed",
RetentionPeriod: 101 * time.Minute,
CRUDLog: platform.CRUDLog{
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},
{
name: "update retention and same name",
fields: BucketFields{
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
Organizations: []*platform.Organization{
{
Name: "theorg",
@ -1215,6 +1251,9 @@ func UpdateBucket(
OrgID: MustIDBase16(orgOneID),
Name: "bucket2",
RetentionPeriod: 101 * time.Minute,
CRUDLog: platform.CRUDLog{
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
},
},

View File

@ -15,6 +15,7 @@ import (
type OnboardingFields struct {
IDGenerator platform.IDGenerator
TokenGenerator platform.TokenGenerator
TimeGenerator platform.TimeGenerator
IsOnboarding bool
}
@ -133,6 +134,7 @@ func Generate(
IDGenerator: &loopIDGenerator{
s: []string{oneID, twoID, threeID, fourID},
},
TimeGenerator: mock.TimeGenerator{FakeValue: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC)},
TokenGenerator: mock.NewTokenGenerator(oneToken, nil),
IsOnboarding: true,
},
@ -161,6 +163,10 @@ func Generate(
Name: "bucket1",
OrgID: MustIDBase16(twoID),
RetentionPeriod: time.Hour * 24 * 7,
CRUDLog: platform.CRUDLog{
CreatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
UpdatedAt: time.Date(2006, 5, 4, 1, 2, 3, 0, time.UTC),
},
},
Auth: &platform.Authorization{
ID: MustIDBase16(fourID),