Fix get object lock configuration handler (#6996)
* fix GetObjectLockConfigurationHandler * cache and use bucket object lock config * subscribe to bucket configuration changes * increase bucket config cache TTL * refactor * Update weed/s3api/s3api_server.go Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * avoid duplidated work * rename variable * Update s3api_object_handlers_put.go * fix routing * admin ui and api handler are consistent now * use fields instead of xml * fix test * address comments * Update weed/s3api/s3api_object_handlers_put.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update test/s3/retention/s3_retention_test.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update weed/s3api/object_lock_utils.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * change error style * errorf --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -17,24 +17,29 @@ import (
|
||||
|
||||
// BucketConfig represents cached bucket configuration
|
||||
type BucketConfig struct {
|
||||
Name string
|
||||
Versioning string // "Enabled", "Suspended", or ""
|
||||
Ownership string
|
||||
ACL []byte
|
||||
Owner string
|
||||
CORS *cors.CORSConfiguration
|
||||
LastModified time.Time
|
||||
Entry *filer_pb.Entry
|
||||
Name string
|
||||
Versioning string // "Enabled", "Suspended", or ""
|
||||
Ownership string
|
||||
ACL []byte
|
||||
Owner string
|
||||
CORS *cors.CORSConfiguration
|
||||
ObjectLockConfig *ObjectLockConfiguration // Cached parsed Object Lock configuration
|
||||
LastModified time.Time
|
||||
Entry *filer_pb.Entry
|
||||
}
|
||||
|
||||
// BucketConfigCache provides caching for bucket configurations
|
||||
// Cache entries are automatically updated/invalidated through metadata subscription events,
|
||||
// so TTL serves as a safety fallback rather than the primary consistency mechanism
|
||||
type BucketConfigCache struct {
|
||||
cache map[string]*BucketConfig
|
||||
mutex sync.RWMutex
|
||||
ttl time.Duration
|
||||
ttl time.Duration // Safety fallback TTL; real-time consistency maintained via events
|
||||
}
|
||||
|
||||
// NewBucketConfigCache creates a new bucket configuration cache
|
||||
// TTL can be set to a longer duration since cache consistency is maintained
|
||||
// through real-time metadata subscription events rather than TTL expiration
|
||||
func NewBucketConfigCache(ttl time.Duration) *BucketConfigCache {
|
||||
return &BucketConfigCache{
|
||||
cache: make(map[string]*BucketConfig),
|
||||
@@ -52,7 +57,7 @@ func (bcc *BucketConfigCache) Get(bucket string) (*BucketConfig, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// Check if cache entry is expired
|
||||
// Check if cache entry is expired (safety fallback; entries are normally updated via events)
|
||||
if time.Since(config.LastModified) > bcc.ttl {
|
||||
return nil, false
|
||||
}
|
||||
@@ -121,6 +126,11 @@ func (s3a *S3ApiServer) getBucketConfig(bucket string) (*BucketConfig, s3err.Err
|
||||
if owner, exists := bucketEntry.Extended[s3_constants.ExtAmzOwnerKey]; exists {
|
||||
config.Owner = string(owner)
|
||||
}
|
||||
// Parse Object Lock configuration if present
|
||||
if objectLockConfig, found := LoadObjectLockConfigurationFromExtended(bucketEntry); found {
|
||||
config.ObjectLockConfig = objectLockConfig
|
||||
glog.V(2).Infof("getBucketConfig: cached Object Lock configuration for bucket %s", bucket)
|
||||
}
|
||||
}
|
||||
|
||||
// Load CORS configuration from .s3metadata
|
||||
@@ -173,6 +183,13 @@ func (s3a *S3ApiServer) updateBucketConfig(bucket string, updateFn func(*BucketC
|
||||
if config.Owner != "" {
|
||||
config.Entry.Extended[s3_constants.ExtAmzOwnerKey] = []byte(config.Owner)
|
||||
}
|
||||
// Update Object Lock configuration
|
||||
if config.ObjectLockConfig != nil {
|
||||
if err := StoreObjectLockConfigurationInExtended(config.Entry, config.ObjectLockConfig); err != nil {
|
||||
glog.Errorf("updateBucketConfig: failed to store Object Lock configuration for bucket %s: %v", bucket, err)
|
||||
return s3err.ErrInternalError
|
||||
}
|
||||
}
|
||||
|
||||
// Save to filer
|
||||
err := s3a.updateEntry(s3a.option.BucketsPath, config.Entry)
|
||||
|
||||
Reference in New Issue
Block a user