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

[ADDED] Object-store-metadata #1385

Merged
merged 1 commit into from
Sep 6, 2023
Merged
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
18 changes: 15 additions & 3 deletions object.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ type ObjectStoreConfig struct {
Storage StorageType `json:"storage,omitempty"`
Replicas int `json:"num_replicas,omitempty"`
Placement *Placement `json:"placement,omitempty"`

// Bucket-specific metadata
// NOTE: Metadata requires nats-server v2.10.0+
Metadata map[string]string `json:"metadata,omitempty"`
}

type ObjectStoreStatus interface {
Expand All @@ -176,6 +180,8 @@ type ObjectStoreStatus interface {
Size() uint64
// BackingStore provides details about the underlying storage
BackingStore() string
// Metadata is the user supplied metadata for the bucket
Metadata() map[string]string
}

// ObjectMetaOptions
Expand All @@ -186,9 +192,10 @@ type ObjectMetaOptions struct {

// ObjectMeta is high level information about an object.
type ObjectMeta struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Headers Header `json:"headers,omitempty"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
Headers Header `json:"headers,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`

// Optional options.
Opts *ObjectMetaOptions `json:"options,omitempty"`
Expand Down Expand Up @@ -280,6 +287,7 @@ func (js *js) CreateObjectStore(cfg *ObjectStoreConfig) (ObjectStore, error) {
Discard: DiscardNew,
AllowRollup: true,
AllowDirect: true,
Metadata: cfg.Metadata,
}

// Create our stream.
Expand Down Expand Up @@ -974,6 +982,7 @@ func (obs *obs) UpdateMeta(name string, meta *ObjectMeta) error {
info.Name = meta.Name
info.Description = meta.Description
info.Headers = meta.Headers
info.Metadata = meta.Metadata

// Prepare the meta message
if err = publishMeta(info, obs.js); err != nil {
Expand Down Expand Up @@ -1197,6 +1206,9 @@ func (s *ObjectBucketStatus) Size() uint64 { return s.nfo.State.Bytes }
// BackingStore indicates what technology is used for storage of the bucket
func (s *ObjectBucketStatus) BackingStore() string { return "JetStream" }

// Metadata is the metadata supplied when creating the bucket
func (s *ObjectBucketStatus) Metadata() map[string]string { return s.nfo.Config.Metadata }

// StreamInfo is the stream info retrieved to create the status
func (s *ObjectBucketStatus) StreamInfo() *StreamInfo { return s.nfo }

Expand Down
29 changes: 24 additions & 5 deletions test/object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,27 +401,45 @@ func TestObjectMetadata(t *testing.T) {
nc, js := jsClient(t, s)
defer nc.Close()

obs, err := js.CreateObjectStore(&nats.ObjectStoreConfig{Bucket: "META-TEST"})
bucketMetadata := map[string]string{"foo": "bar", "baz": "boo"}
obs, err := js.CreateObjectStore(&nats.ObjectStoreConfig{
Bucket: "META-TEST",
Metadata: bucketMetadata,
})
expectOk(t, err)
status, err := obs.Status()
expectOk(t, err)
if !reflect.DeepEqual(status.Metadata(), bucketMetadata) {
t.Fatalf("invalid bucket metadata: %+v", status.Metadata())
}

// Simple with no Meta.
_, err = obs.PutString("A", "AAA")
expectOk(t, err)
_, err = obs.PutString("C", "CCC")
buf := bytes.NewBufferString("CCC")
objectMetadata := map[string]string{"name": "C", "description": "descC"}
info, err := obs.Put(&nats.ObjectMeta{Name: "C", Metadata: objectMetadata}, buf)
expectOk(t, err)
if !reflect.DeepEqual(info.Metadata, objectMetadata) {
t.Fatalf("invalid object metadata: %+v", info.Metadata)
}

meta := &nats.ObjectMeta{Name: "A"}
meta.Description = "descA"
meta.Headers = make(nats.Header)
meta.Headers.Set("color", "blue")
objectMetadata["description"] = "updated desc"
objectMetadata["version"] = "0.1"
meta.Metadata = objectMetadata

// simple update that does not change the name, just adds data
err = obs.UpdateMeta("A", meta)
expectOk(t, err)

info, err := obs.GetInfo("A")
info, err = obs.GetInfo("A")
expectOk(t, err)
if info.Name != "A" || info.Description != "descA" || info.Headers == nil || info.Headers.Get("color") != "blue" {
if info.Name != "A" || info.Description != "descA" || info.Headers == nil || info.Headers.Get("color") != "blue" ||
!reflect.DeepEqual(info.Metadata, objectMetadata) {
t.Fatalf("Update failed: %+v", info)
}

Expand All @@ -430,6 +448,7 @@ func TestObjectMetadata(t *testing.T) {
meta.Description = "descB"
meta.Headers = make(nats.Header)
meta.Headers.Set("color", "red")
meta.Metadata = nil

err = obs.UpdateMeta("A", meta)
expectOk(t, err)
Expand All @@ -441,7 +460,7 @@ func TestObjectMetadata(t *testing.T) {

info, err = obs.GetInfo("B")
expectOk(t, err)
if info.Name != "B" || info.Description != "descB" || info.Headers == nil || info.Headers.Get("color") != "red" {
if info.Name != "B" || info.Description != "descB" || info.Headers == nil || info.Headers.Get("color") != "red" || info.Metadata != nil {
t.Fatalf("Update failed: %+v", info)
}

Expand Down