cached_policy_store_generic.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package policy
  2. import (
  3. "context"
  4. "encoding/json"
  5. "time"
  6. "github.com/seaweedfs/seaweedfs/weed/glog"
  7. "github.com/seaweedfs/seaweedfs/weed/iam/util"
  8. )
  9. // PolicyStoreAdapter adapts PolicyStore interface to CacheableStore[*PolicyDocument]
  10. type PolicyStoreAdapter struct {
  11. store PolicyStore
  12. }
  13. // NewPolicyStoreAdapter creates a new adapter for PolicyStore
  14. func NewPolicyStoreAdapter(store PolicyStore) *PolicyStoreAdapter {
  15. return &PolicyStoreAdapter{store: store}
  16. }
  17. // Get implements CacheableStore interface
  18. func (a *PolicyStoreAdapter) Get(ctx context.Context, filerAddress string, key string) (*PolicyDocument, error) {
  19. return a.store.GetPolicy(ctx, filerAddress, key)
  20. }
  21. // Store implements CacheableStore interface
  22. func (a *PolicyStoreAdapter) Store(ctx context.Context, filerAddress string, key string, value *PolicyDocument) error {
  23. return a.store.StorePolicy(ctx, filerAddress, key, value)
  24. }
  25. // Delete implements CacheableStore interface
  26. func (a *PolicyStoreAdapter) Delete(ctx context.Context, filerAddress string, key string) error {
  27. return a.store.DeletePolicy(ctx, filerAddress, key)
  28. }
  29. // List implements CacheableStore interface
  30. func (a *PolicyStoreAdapter) List(ctx context.Context, filerAddress string) ([]string, error) {
  31. return a.store.ListPolicies(ctx, filerAddress)
  32. }
  33. // GenericCachedPolicyStore implements PolicyStore using the generic cache
  34. type GenericCachedPolicyStore struct {
  35. *util.CachedStore[*PolicyDocument]
  36. adapter *PolicyStoreAdapter
  37. }
  38. // NewGenericCachedPolicyStore creates a new cached policy store using generics
  39. func NewGenericCachedPolicyStore(config map[string]interface{}, filerAddressProvider func() string) (*GenericCachedPolicyStore, error) {
  40. // Create underlying filer store
  41. filerStore, err := NewFilerPolicyStore(config, filerAddressProvider)
  42. if err != nil {
  43. return nil, err
  44. }
  45. // Parse cache configuration with defaults
  46. cacheTTL := 5 * time.Minute
  47. listTTL := 1 * time.Minute
  48. maxCacheSize := int64(500)
  49. if config != nil {
  50. if ttlStr, ok := config["ttl"].(string); ok && ttlStr != "" {
  51. if parsed, err := time.ParseDuration(ttlStr); err == nil {
  52. cacheTTL = parsed
  53. }
  54. }
  55. if listTTLStr, ok := config["listTtl"].(string); ok && listTTLStr != "" {
  56. if parsed, err := time.ParseDuration(listTTLStr); err == nil {
  57. listTTL = parsed
  58. }
  59. }
  60. if maxSize, ok := config["maxCacheSize"].(int); ok && maxSize > 0 {
  61. maxCacheSize = int64(maxSize)
  62. }
  63. }
  64. // Create adapter and generic cached store
  65. adapter := NewPolicyStoreAdapter(filerStore)
  66. cachedStore := util.NewCachedStore(
  67. adapter,
  68. genericCopyPolicyDocument, // Copy function
  69. util.CachedStoreConfig{
  70. TTL: cacheTTL,
  71. ListTTL: listTTL,
  72. MaxCacheSize: maxCacheSize,
  73. },
  74. )
  75. glog.V(2).Infof("Initialized GenericCachedPolicyStore with TTL %v, List TTL %v, Max Cache Size %d",
  76. cacheTTL, listTTL, maxCacheSize)
  77. return &GenericCachedPolicyStore{
  78. CachedStore: cachedStore,
  79. adapter: adapter,
  80. }, nil
  81. }
  82. // StorePolicy implements PolicyStore interface
  83. func (c *GenericCachedPolicyStore) StorePolicy(ctx context.Context, filerAddress string, name string, policy *PolicyDocument) error {
  84. return c.Store(ctx, filerAddress, name, policy)
  85. }
  86. // GetPolicy implements PolicyStore interface
  87. func (c *GenericCachedPolicyStore) GetPolicy(ctx context.Context, filerAddress string, name string) (*PolicyDocument, error) {
  88. return c.Get(ctx, filerAddress, name)
  89. }
  90. // ListPolicies implements PolicyStore interface
  91. func (c *GenericCachedPolicyStore) ListPolicies(ctx context.Context, filerAddress string) ([]string, error) {
  92. return c.List(ctx, filerAddress)
  93. }
  94. // DeletePolicy implements PolicyStore interface
  95. func (c *GenericCachedPolicyStore) DeletePolicy(ctx context.Context, filerAddress string, name string) error {
  96. return c.Delete(ctx, filerAddress, name)
  97. }
  98. // genericCopyPolicyDocument creates a deep copy of a PolicyDocument for the generic cache
  99. func genericCopyPolicyDocument(policy *PolicyDocument) *PolicyDocument {
  100. if policy == nil {
  101. return nil
  102. }
  103. // Perform a deep copy to ensure cache isolation
  104. // Using JSON marshaling is a safe way to achieve this
  105. policyData, err := json.Marshal(policy)
  106. if err != nil {
  107. glog.Errorf("Failed to marshal policy document for deep copy: %v", err)
  108. return nil
  109. }
  110. var copied PolicyDocument
  111. if err := json.Unmarshal(policyData, &copied); err != nil {
  112. glog.Errorf("Failed to unmarshal policy document for deep copy: %v", err)
  113. return nil
  114. }
  115. return &copied
  116. }