Files
ragflow/internal/storage/storage_factory.go
Jin Hai 9ce766192f Init storage engine (#13707)
### What problem does this PR solve?

1. Init Minio / S3 / OSS
2. Fix minio / s3 / oss config

### Type of change

- [x] New Feature (non-breaking change which adds functionality)

---------

Signed-off-by: Jin Hai <haijin.chn@gmail.com>
2026-03-20 13:15:41 +08:00

201 lines
5.0 KiB
Go

//
// Copyright 2026 The InfiniFlow Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package storage
import (
"fmt"
"ragflow/internal/logger"
"ragflow/internal/server"
"sync"
)
var (
globalFactory *StorageFactory
once sync.Once
)
// StorageFactory creates storage instances based on configuration
type StorageFactory struct {
storageType StorageType
storage Storage
config *server.StorageConfig
mu sync.RWMutex
}
// GetStorageFactory returns the singleton storage factory instance
func GetStorageFactory() *StorageFactory {
once.Do(func() {
globalFactory = &StorageFactory{}
})
return globalFactory
}
// InitStorageFactory initializes the storage factory with configuration
func InitStorageFactory() error {
factory := GetStorageFactory()
globalConfig := server.GetConfig()
factory.config = &globalConfig.StorageEngine
// Initialize storage based on type
if err := factory.initStorage(); err != nil {
return err
}
logger.Info(fmt.Sprintf("Storage initialized: %s", factory.config.Type))
return nil
}
// initStorage initializes the specific storage implementation
func (f *StorageFactory) initStorage() error {
switch f.config.Type {
case "minio":
return f.initMinio(f.config.Minio)
case "s3":
return f.initS3(f.config.S3)
case "oss":
return f.initOSS(f.config.OSS)
default:
return fmt.Errorf("unsupported storage type: %s", f.config.Type)
}
}
func (f *StorageFactory) initMinio(minioConfig *server.MinioConfig) error {
storage, err := NewMinioStorage(minioConfig)
if err != nil {
return fmt.Errorf("failed to create MinIO storage: %w", err)
}
f.mu.Lock()
defer f.mu.Unlock()
f.storageType = StorageMinio
f.storage = storage
f.config.Minio = minioConfig
return nil
}
func (f *StorageFactory) initS3(s3Config *server.S3Config) error {
storage, err := NewS3Storage(s3Config)
if err != nil {
return fmt.Errorf("failed to create S3 storage: %w", err)
}
f.mu.Lock()
defer f.mu.Unlock()
f.storageType = StorageAWSS3
f.storage = storage
f.config.S3 = s3Config
return nil
}
func (f *StorageFactory) initOSS(ossConfig *server.OSSConfig) error {
storage, err := NewOSSStorage(ossConfig)
if err != nil {
return fmt.Errorf("failed to create OSS storage: %w", err)
}
f.mu.Lock()
defer f.mu.Unlock()
f.storageType = StorageOSS
f.storage = storage
f.config.OSS = ossConfig
return nil
}
// GetStorage returns the current storage instance
func (f *StorageFactory) GetStorage() Storage {
f.mu.RLock()
defer f.mu.RUnlock()
return f.storage
}
// GetStorageType returns the current storage type
func (f *StorageFactory) GetStorageType() StorageType {
f.mu.RLock()
defer f.mu.RUnlock()
return f.storageType
}
// Create creates a new storage instance based on the storage type
// This is the factory method equivalent to Python's StorageFactory.create()
func (f *StorageFactory) Create(storageType StorageType) (Storage, error) {
var storage Storage
var err error
switch storageType {
case StorageMinio:
if f.config.Minio != nil {
storage, err = NewMinioStorage(f.config.Minio)
} else {
return nil, fmt.Errorf("MinIO config not available")
}
case StorageAWSS3:
if f.config.S3 != nil {
storage, err = NewS3Storage(f.config.S3)
} else {
return nil, fmt.Errorf("S3 config not available")
}
case StorageOSS:
if f.config.OSS != nil {
storage, err = NewOSSStorage(f.config.OSS)
} else {
return nil, fmt.Errorf("OSS config not available")
}
default:
return nil, fmt.Errorf("unsupported storage type: %v", storageType)
}
if err != nil {
return nil, err
}
return storage, nil
}
// SetStorage sets the storage instance (useful for testing)
func (f *StorageFactory) SetStorage(storage Storage) {
f.mu.Lock()
defer f.mu.Unlock()
f.storage = storage
}
// StorageTypeMapping returns the storage type mapping (equivalent to Python's storage_mapping)
var StorageTypeMapping = map[StorageType]func(*server.StorageConfig) (Storage, error){
StorageMinio: func(config *server.StorageConfig) (Storage, error) {
if config.Minio == nil {
return nil, fmt.Errorf("MinIO config not available")
}
return NewMinioStorage(config.Minio)
},
StorageAWSS3: func(config *server.StorageConfig) (Storage, error) {
if config.S3 == nil {
return nil, fmt.Errorf("S3 config not available")
}
return NewS3Storage(config.S3)
},
StorageOSS: func(config *server.StorageConfig) (Storage, error) {
if config.OSS == nil {
return nil, fmt.Errorf("OSS config not available")
}
return NewOSSStorage(config.OSS)
},
}