package policy import ( "encoding/json" "fmt" policycontract "git.frostfs.info/TrueCloudLab/frostfs-contract/policy" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/cache" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/handler" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs" "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" "git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine" "github.com/nspcc-dev/neo-go/pkg/util" "go.uber.org/zap" ) type MorphRuleChainStorage struct { contract Contract cache *cache.MorphPolicyCache log *zap.Logger } type MorphRuleChainStorageConfig struct { Contract Contract Cache *cache.MorphPolicyCache Log *zap.Logger } var ( _ engine.MorphRuleChainStorage = (*MorphRuleChainStorage)(nil) _ handler.MorphRuleChainStorage = (*MorphRuleChainStorage)(nil) ) func NewMorphRuleChainStorage(config *MorphRuleChainStorageConfig) *MorphRuleChainStorage { return &MorphRuleChainStorage{ contract: config.Contract, cache: config.Cache, log: config.Log, } } func (c *MorphRuleChainStorage) AddChain(target engine.Target, policyChain *chain.Chain) error { return c.contract.Wait(c.AddMorphRuleChain(chain.S3, target, policyChain)) } func (c *MorphRuleChainStorage) RemoveChain(target engine.Target, chainID chain.ID) error { return c.contract.Wait(c.RemoveMorphRuleChain(chain.S3, target, chainID)) } func (c *MorphRuleChainStorage) ListChains(target engine.Target) ([]*chain.Chain, error) { return c.ListMorphRuleChains(chain.S3, target) } func (c *MorphRuleChainStorage) AddMorphRuleChain(name chain.Name, target engine.Target, policyChain *chain.Chain) (util.Uint256, uint32, error) { c.cache.Delete(cache.MorphPolicyCacheKey{Target: target, Name: name}) return c.contract.AddChain(getKind(target), target.Name, getName(name, policyChain.ID), policyChain.Bytes()) } func (c *MorphRuleChainStorage) RemoveMorphRuleChain(name chain.Name, target engine.Target, chainID chain.ID) (util.Uint256, uint32, error) { c.cache.Delete(cache.MorphPolicyCacheKey{Target: target, Name: name}) return c.contract.RemoveChain(getKind(target), target.Name, getName(name, chainID)) } func (c *MorphRuleChainStorage) ListMorphRuleChains(name chain.Name, target engine.Target) ([]*chain.Chain, error) { key := cache.MorphPolicyCacheKey{Target: target, Name: name} list := c.cache.Get(key) if list != nil { return list, nil } listChains, err := c.contract.ListChains(getKind(target), target.Name, []byte(name)) if err != nil { return nil, err } list = make([]*chain.Chain, len(listChains)) for i, listChain := range listChains { var item chain.Chain if err = json.Unmarshal(listChain, &item); err != nil { return nil, fmt.Errorf("unmarshal chain: %w", err) } list[i] = &item } if err = c.cache.Put(key, list); err != nil { c.log.Warn(logs.CouldntCacheListPolicyChains) } return list, nil } func getKind(target engine.Target) policycontract.Kind { var kind policycontract.Kind = policycontract.Container if target.Type != engine.Container { kind = policycontract.Namespace } return kind } func getName(name chain.Name, chainID chain.ID) []byte { return append([]byte(name), []byte(chainID)...) }