forked from TrueCloudLab/frostfs-api-go
[#283] v2/session: Support ContainerSessionContext message
Define `ContainerSessionContext` structure, implement getters / setters, JSON and binary encoders, gRPC converters. Support new type of context in SessionTokenBody message. Add test message generator and cover methods with unit tests. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
f2be7509d3
commit
9eb567a53a
6 changed files with 261 additions and 0 deletions
|
@ -707,6 +707,8 @@ func (t *SessionTokenBody) ToGRPCMessage() grpc.Message {
|
||||||
m.Context = nil
|
m.Context = nil
|
||||||
case *ObjectSessionContext:
|
case *ObjectSessionContext:
|
||||||
m.SetObjectSessionContext(typ.ToGRPCMessage().(*session.ObjectSessionContext))
|
m.SetObjectSessionContext(typ.ToGRPCMessage().(*session.ObjectSessionContext))
|
||||||
|
case *ContainerSessionContext:
|
||||||
|
m.SetContainerSessionContext(typ.ToGRPCMessage().(*session.ContainerSessionContext))
|
||||||
}
|
}
|
||||||
|
|
||||||
m.SetOwnerId(t.ownerID.ToGRPCMessage().(*refsGRPC.OwnerID))
|
m.SetOwnerId(t.ownerID.ToGRPCMessage().(*refsGRPC.OwnerID))
|
||||||
|
@ -740,6 +742,14 @@ func (t *SessionTokenBody) FromGRPCMessage(m grpc.Message) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ctx.FromGRPCMessage(val.Object)
|
err = ctx.FromGRPCMessage(val.Object)
|
||||||
|
case *session.SessionToken_Body_Container:
|
||||||
|
ctx, ok := t.ctx.(*ContainerSessionContext)
|
||||||
|
if !ok {
|
||||||
|
ctx = new(ContainerSessionContext)
|
||||||
|
t.ctx = ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ctx.FromGRPCMessage(val.Container)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -779,3 +789,87 @@ func (t *SessionTokenBody) FromGRPCMessage(m grpc.Message) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContainerSessionVerbToGRPCField converts ContainerSessionVerb
|
||||||
|
// to gRPC-generated session.ContainerSessionContext_Verb.
|
||||||
|
//
|
||||||
|
// If v is outside of the ContainerSessionVerb enum,
|
||||||
|
// session.ContainerSessionContext_VERB_UNSPECIFIED is returned.
|
||||||
|
func ContainerSessionVerbToGRPCField(v ContainerSessionVerb) session.ContainerSessionContext_Verb {
|
||||||
|
switch v {
|
||||||
|
default:
|
||||||
|
return session.ContainerSessionContext_VERB_UNSPECIFIED
|
||||||
|
case ContainerVerbPut:
|
||||||
|
return session.ContainerSessionContext_PUT
|
||||||
|
case ContainerVerbDelete:
|
||||||
|
return session.ContainerSessionContext_DELETE
|
||||||
|
case ContainerVerbSetEACL:
|
||||||
|
return session.ContainerSessionContext_SETEACL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerSessionVerbFromGRPCField converts gRPC-generated
|
||||||
|
// session.ContainerSessionContext_Verb to ContainerSessionVerb.
|
||||||
|
//
|
||||||
|
// If v is outside of the session.ContainerSessionContext_Verb enum,
|
||||||
|
// ContainerVerbUnknown is returned.
|
||||||
|
func ContainerSessionVerbFromGRPCField(v session.ContainerSessionContext_Verb) ContainerSessionVerb {
|
||||||
|
switch v {
|
||||||
|
default:
|
||||||
|
return ContainerVerbUnknown
|
||||||
|
case session.ContainerSessionContext_PUT:
|
||||||
|
return ContainerVerbPut
|
||||||
|
case session.ContainerSessionContext_DELETE:
|
||||||
|
return ContainerVerbDelete
|
||||||
|
case session.ContainerSessionContext_SETEACL:
|
||||||
|
return ContainerVerbSetEACL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToGRPCMessage converts ContainerSessionContext to gRPC-generated
|
||||||
|
// session.ContainerSessionContext message.
|
||||||
|
func (x *ContainerSessionContext) ToGRPCMessage() grpc.Message {
|
||||||
|
var m *session.ContainerSessionContext
|
||||||
|
|
||||||
|
if x != nil {
|
||||||
|
m = new(session.ContainerSessionContext)
|
||||||
|
|
||||||
|
m.SetVerb(ContainerSessionVerbToGRPCField(x.verb))
|
||||||
|
m.SetWildcard(x.wildcard)
|
||||||
|
m.SetContainerId(x.cid.ToGRPCMessage().(*refsGRPC.ContainerID))
|
||||||
|
}
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromGRPCMessage tries to restore ContainerSessionContext from grpc.Message.
|
||||||
|
//
|
||||||
|
// Returns message.ErrUnexpectedMessageType if m is not
|
||||||
|
// a gRPC-generated session.ContainerSessionContext message.
|
||||||
|
func (x *ContainerSessionContext) FromGRPCMessage(m grpc.Message) error {
|
||||||
|
v, ok := m.(*session.ContainerSessionContext)
|
||||||
|
if !ok {
|
||||||
|
return message.NewUnexpectedMessageType(m, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
|
||||||
|
cid := v.GetContainerId()
|
||||||
|
if cid == nil {
|
||||||
|
x.cid = nil
|
||||||
|
} else {
|
||||||
|
if x.cid == nil {
|
||||||
|
x.cid = new(refs.ContainerID)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = x.cid.FromGRPCMessage(cid)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x.verb = ContainerSessionVerbFromGRPCField(v.GetVerb())
|
||||||
|
x.wildcard = v.GetWildcard()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -119,3 +119,11 @@ func (r *ResponseVerificationHeader) UnmarshalJSON(data []byte) error {
|
||||||
|
|
||||||
return r.FromGRPCMessage(msg)
|
return r.FromGRPCMessage(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *ContainerSessionContext) MarshalJSON() ([]byte, error) {
|
||||||
|
return message.MarshalJSON(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ContainerSessionContext) UnmarshalJSON(data []byte) error {
|
||||||
|
return message.UnmarshalJSON(x, data, new(session.ContainerSessionContext))
|
||||||
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ const (
|
||||||
sessionTokenBodyLifetimeField = 3
|
sessionTokenBodyLifetimeField = 3
|
||||||
sessionTokenBodyKeyField = 4
|
sessionTokenBodyKeyField = 4
|
||||||
sessionTokenBodyObjectCtxField = 5
|
sessionTokenBodyObjectCtxField = 5
|
||||||
|
sessionTokenBodyCnrCtxField = 6
|
||||||
|
|
||||||
sessionTokenBodyField = 1
|
sessionTokenBodyField = 1
|
||||||
sessionTokenSignatureField = 2
|
sessionTokenSignatureField = 2
|
||||||
|
@ -301,6 +302,65 @@ func (c *ObjectSessionContext) Unmarshal(data []byte) error {
|
||||||
return c.FromGRPCMessage(m)
|
return c.FromGRPCMessage(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ = iota
|
||||||
|
cnrCtxVerbFNum
|
||||||
|
cnrCtxWildcardFNum
|
||||||
|
cnrCtxCidFNum
|
||||||
|
)
|
||||||
|
|
||||||
|
func (x *ContainerSessionContext) StableMarshal(buf []byte) ([]byte, error) {
|
||||||
|
if x == nil {
|
||||||
|
return []byte{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if buf == nil {
|
||||||
|
buf = make([]byte, x.StableSize())
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
offset, n int
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
n, err = proto.EnumMarshal(cnrCtxVerbFNum, buf[offset:], int32(ContainerSessionVerbToGRPCField(x.verb)))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += n
|
||||||
|
|
||||||
|
n, err = proto.BoolMarshal(cnrCtxWildcardFNum, buf[offset:], x.wildcard)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += n
|
||||||
|
|
||||||
|
_, err = proto.NestedStructureMarshal(cnrCtxCidFNum, buf[offset:], x.cid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ContainerSessionContext) StableSize() (size int) {
|
||||||
|
if x == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
size += proto.EnumSize(cnrCtxVerbFNum, int32(ContainerSessionVerbToGRPCField(x.verb)))
|
||||||
|
size += proto.BoolSize(cnrCtxWildcardFNum, x.wildcard)
|
||||||
|
size += proto.NestedStructureSize(cnrCtxCidFNum, x.cid)
|
||||||
|
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ContainerSessionContext) Unmarshal(data []byte) error {
|
||||||
|
return message.Unmarshal(x, data, new(session.ContainerSessionContext))
|
||||||
|
}
|
||||||
|
|
||||||
func (t *SessionTokenBody) StableMarshal(buf []byte) ([]byte, error) {
|
func (t *SessionTokenBody) StableMarshal(buf []byte) ([]byte, error) {
|
||||||
if t == nil {
|
if t == nil {
|
||||||
return []byte{}, nil
|
return []byte{}, nil
|
||||||
|
@ -350,6 +410,11 @@ func (t *SessionTokenBody) StableMarshal(buf []byte) ([]byte, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
case *ContainerSessionContext:
|
||||||
|
_, err = proto.NestedStructureMarshal(sessionTokenBodyCnrCtxField, buf[offset:], v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
panic("cannot marshal unknown session token context")
|
panic("cannot marshal unknown session token context")
|
||||||
}
|
}
|
||||||
|
@ -372,6 +437,8 @@ func (t *SessionTokenBody) StableSize() (size int) {
|
||||||
switch v := t.ctx.(type) {
|
switch v := t.ctx.(type) {
|
||||||
case *ObjectSessionContext:
|
case *ObjectSessionContext:
|
||||||
size += proto.NestedStructureSize(sessionTokenBodyObjectCtxField, v)
|
size += proto.NestedStructureSize(sessionTokenBodyObjectCtxField, v)
|
||||||
|
case *ContainerSessionContext:
|
||||||
|
size += proto.NestedStructureSize(sessionTokenBodyCnrCtxField, v)
|
||||||
default:
|
default:
|
||||||
panic("cannot marshal unknown session token context")
|
panic("cannot marshal unknown session token context")
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,5 +22,6 @@ func TestMessageConvert(t *testing.T) {
|
||||||
func(empty bool) message.Message { return sessiontest.GenerateRequestVerificationHeader(empty) },
|
func(empty bool) message.Message { return sessiontest.GenerateRequestVerificationHeader(empty) },
|
||||||
func(empty bool) message.Message { return sessiontest.GenerateResponseMetaHeader(empty) },
|
func(empty bool) message.Message { return sessiontest.GenerateResponseMetaHeader(empty) },
|
||||||
func(empty bool) message.Message { return sessiontest.GenerateResponseVerificationHeader(empty) },
|
func(empty bool) message.Message { return sessiontest.GenerateResponseVerificationHeader(empty) },
|
||||||
|
func(empty bool) message.Message { return sessiontest.GenerateContainerSessionContext(empty) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,6 +179,19 @@ func GenerateObjectSessionContext(empty bool) *session.ObjectSessionContext {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GenerateContainerSessionContext(empty bool) *session.ContainerSessionContext {
|
||||||
|
m := new(session.ContainerSessionContext)
|
||||||
|
|
||||||
|
if !empty {
|
||||||
|
m.SetVerb(session.ContainerVerbDelete)
|
||||||
|
m.SetWildcard(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.SetContainerID(refstest.GenerateContainerID(empty))
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
func GenerateXHeader(empty bool) *session.XHeader {
|
func GenerateXHeader(empty bool) *session.XHeader {
|
||||||
m := new(session.XHeader)
|
m := new(session.XHeader)
|
||||||
|
|
||||||
|
|
|
@ -735,3 +735,81 @@ func (t *SessionToken) SetSignature(v *refs.Signature) {
|
||||||
t.sig = v
|
t.sig = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContainerSessionVerb represents NeoFS API v2
|
||||||
|
// session.ContainerSessionContext.Verb enumeration.
|
||||||
|
type ContainerSessionVerb uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ContainerVerbUnknown corresponds to VERB_UNSPECIFIED enum value.
|
||||||
|
ContainerVerbUnknown ContainerSessionVerb = iota
|
||||||
|
|
||||||
|
// ContainerVerbPut corresponds to PUT enum value.
|
||||||
|
ContainerVerbPut
|
||||||
|
|
||||||
|
// ContainerVerbDelete corresponds to DELETE enum value.
|
||||||
|
ContainerVerbDelete
|
||||||
|
|
||||||
|
// ContainerVerbSetEACL corresponds to SETEACL enum value.
|
||||||
|
ContainerVerbSetEACL
|
||||||
|
)
|
||||||
|
|
||||||
|
// ContainerSessionContext represents structure of the
|
||||||
|
// NeoFS API v2 session.ContainerSessionContext message.
|
||||||
|
type ContainerSessionContext struct {
|
||||||
|
verb ContainerSessionVerb
|
||||||
|
|
||||||
|
wildcard bool
|
||||||
|
|
||||||
|
cid *refs.ContainerID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ContainerSessionContext) sessionTokenContext() {}
|
||||||
|
|
||||||
|
// Verb returns type of request for which the token is issued.
|
||||||
|
func (x *ContainerSessionContext) Verb() ContainerSessionVerb {
|
||||||
|
if x != nil {
|
||||||
|
return x.verb
|
||||||
|
}
|
||||||
|
|
||||||
|
return ContainerVerbUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetVerb sets type of request for which the token is issued.
|
||||||
|
func (x *ContainerSessionContext) SetVerb(v ContainerSessionVerb) {
|
||||||
|
if x != nil {
|
||||||
|
x.verb = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wildcard returns wildcard flag of the container session.
|
||||||
|
func (x *ContainerSessionContext) Wildcard() bool {
|
||||||
|
if x != nil {
|
||||||
|
return x.wildcard
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetWildcard sets wildcard flag of the container session.
|
||||||
|
func (x *ContainerSessionContext) SetWildcard(v bool) {
|
||||||
|
if x != nil {
|
||||||
|
x.wildcard = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerID returns identifier of the container related to the session.
|
||||||
|
func (x *ContainerSessionContext) ContainerID() *refs.ContainerID {
|
||||||
|
if x != nil {
|
||||||
|
return x.cid
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetContainerID sets identifier of the container related to the session.
|
||||||
|
func (x *ContainerSessionContext) SetContainerID(v *refs.ContainerID) {
|
||||||
|
if x != nil {
|
||||||
|
x.cid = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue