97 lines
2.4 KiB
Go
97 lines
2.4 KiB
Go
package contract
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"sync"
|
|
|
|
policycontract "git.frostfs.info/TrueCloudLab/frostfs-contract/policy"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/policy"
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
)
|
|
|
|
type InMemoryContract struct {
|
|
iamChains *syncedMap
|
|
containerChains *syncedMap
|
|
namespaceChains *syncedMap
|
|
}
|
|
|
|
type syncedMap struct {
|
|
mu sync.RWMutex
|
|
data map[string][]byte
|
|
}
|
|
|
|
var _ policy.Contract = (*InMemoryContract)(nil)
|
|
|
|
var ErrChainNotFound = errors.New("chain not found")
|
|
|
|
// NewInMemoryContract creates new inmemory Policy contract wrapper.
|
|
func NewInMemoryContract() *InMemoryContract {
|
|
return &InMemoryContract{
|
|
iamChains: &syncedMap{data: map[string][]byte{}},
|
|
containerChains: &syncedMap{data: map[string][]byte{}},
|
|
namespaceChains: &syncedMap{data: map[string][]byte{}},
|
|
}
|
|
}
|
|
|
|
func (c *InMemoryContract) AddChain(kind policycontract.Kind, entity string, name []byte, chain []byte) (util.Uint256, uint32, error) {
|
|
syncMap := c.getMap(kind)
|
|
syncMap.mu.Lock()
|
|
syncMap.data[entity+string(name)] = chain
|
|
syncMap.mu.Unlock()
|
|
|
|
return util.Uint256{}, 0, nil
|
|
}
|
|
|
|
func (c *InMemoryContract) GetChain(kind policycontract.Kind, entity string, name []byte) ([]byte, error) {
|
|
syncMap := c.getMap(kind)
|
|
syncMap.mu.RLock()
|
|
defer syncMap.mu.RUnlock()
|
|
|
|
val, ok := syncMap.data[entity+string(name)]
|
|
if !ok {
|
|
return nil, ErrChainNotFound
|
|
}
|
|
return val, nil
|
|
}
|
|
|
|
func (c *InMemoryContract) RemoveChain(kind policycontract.Kind, entity string, name []byte) (util.Uint256, uint32, error) {
|
|
syncMap := c.getMap(kind)
|
|
syncMap.mu.Lock()
|
|
delete(syncMap.data, entity+string(name))
|
|
syncMap.mu.Unlock()
|
|
|
|
return util.Uint256{}, 0, nil
|
|
}
|
|
|
|
func (c *InMemoryContract) ListChains(kind policycontract.Kind, entity string, name []byte) ([][]byte, error) {
|
|
syncMap := c.getMap(kind)
|
|
syncMap.mu.RLock()
|
|
defer syncMap.mu.RUnlock()
|
|
|
|
var res [][]byte
|
|
for key, val := range syncMap.data {
|
|
if strings.HasPrefix(key, entity+string(name)) {
|
|
res = append(res, val)
|
|
}
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func (c *InMemoryContract) Wait(_ util.Uint256, _ uint32, err error) error {
|
|
return err
|
|
}
|
|
|
|
func (c *InMemoryContract) getMap(kind policycontract.Kind) *syncedMap {
|
|
switch kind {
|
|
case policycontract.IAM:
|
|
return c.iamChains
|
|
case policycontract.Container:
|
|
return c.containerChains
|
|
case policycontract.Namespace:
|
|
return c.namespaceChains
|
|
default:
|
|
return &syncedMap{data: map[string][]byte{}}
|
|
}
|
|
}
|