diff --git a/container/container.go b/container/container.go index 7ecf1431..9c6c0f87 100644 --- a/container/container.go +++ b/container/container.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "strconv" + "strings" "time" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container" @@ -296,7 +297,7 @@ func (x Container) PlacementPolicy() (res netmap.PlacementPolicy) { // // SetAttribute overwrites existing attribute value. // -// See also Attribute, IterateAttributes. +// See also Attribute, IterateAttributes, IterateUserAttributes. func (x *Container) SetAttribute(key, value string) { if key == "" { panic("empty attribute key") @@ -324,7 +325,7 @@ func (x *Container) SetAttribute(key, value string) { // Attribute reads value of the Container attribute by key. Empty result means // attribute absence. // -// See also SetAttribute, IterateAttributes. +// See also SetAttribute, IterateAttributes, IterateUserAttributes. func (x Container) Attribute(key string) string { attrs := x.v2.GetAttributes() for i := range attrs { @@ -347,6 +348,21 @@ func (x Container) IterateAttributes(f func(key, val string)) { } } +// IterateUserAttributes iterates over user Container attributes and passes them +// into f. The handler MUST NOT be nil. +// +// See also SetAttribute, Attribute. +func (x Container) IterateUserAttributes(f func(key, val string)) { + attrs := x.v2.GetAttributes() + for _, attr := range attrs { + var key = attr.GetKey() + if !strings.HasPrefix(key, container.SysAttributePrefix) && + !strings.HasPrefix(key, container.SysAttributePrefixNeoFS) { + f(key, attr.GetValue()) + } + } +} + // SetName sets human-readable name of the Container. Name MUST NOT be empty. // // See also Name. diff --git a/container/container_test.go b/container/container_test.go index b3ab719a..f0a22447 100644 --- a/container/container_test.go +++ b/container/container_test.go @@ -150,7 +150,7 @@ func assertContainsAttribute(t *testing.T, m v2container.Container, key, val str } func TestContainer_Attribute(t *testing.T) { - const attrKey1, attrKey2 = "key1", "key2" + const attrKey1, attrKey2 = v2container.SysAttributePrefix + "key1", v2container.SysAttributePrefixNeoFS + "key2" const attrVal1, attrVal2 = "val1", "val2" val := containertest.Container() @@ -158,6 +158,12 @@ func TestContainer_Attribute(t *testing.T) { val.SetAttribute(attrKey1, attrVal1) val.SetAttribute(attrKey2, attrVal2) + var i int + val.IterateUserAttributes(func(key, val string) { + i++ + }) + require.Equal(t, 1, i) + var msg v2container.Container val.WriteToV2(&msg)