You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

306 lines
7.3 KiB

package service
import (
"context"
"fmt"
"sync"
"time"
"market-data-service/adapter"
"market-data-service/adapter/tushare"
"market-data-service/api"
)
// AdapterService 适配器管理服务接口
type AdapterService interface {
// GetAdapterList 获取适配器列表
GetAdapterList(ctx context.Context) (*api.AdapterListData, error)
// ToggleAdapter 启用/禁用适配器
ToggleAdapter(ctx context.Context, req *api.AdapterToggleRequest) error
// UpdateAdapterConfig 更新适配器配置
UpdateAdapterConfig(ctx context.Context, req *api.AdapterConfigUpdateRequest) error
// GetActiveAdapter 获取当前激活的适配器
GetActiveAdapter(assetClass string) (adapter.DataSourceAdapter, error)
// GetAvailableAdapters 获取所有可用的适配器名称
GetAvailableAdapters() []string
// RegisterAdapter 注册适配器
RegisterAdapter(name string, factory AdapterFactory)
}
// AdapterFactory 适配器工厂函数
type AdapterFactory func() adapter.DataSourceAdapter
// AdapterServiceImpl 适配器服务实现
type AdapterServiceImpl struct {
mu sync.RWMutex
// 已注册的适配器工厂
factories map[string]AdapterFactory
// 适配器配置
configs map[string]*adapterConfig
// 当前激活的适配器实例
activeAdapters map[string]adapter.DataSourceAdapter
// 适配器元数据
metadata map[string]*adapterMetadata
}
// adapterConfig 适配器配置
type adapterConfig struct {
Enabled bool `json:"enabled"`
Config map[string]string `json:"config"`
}
// adapterMetadata 适配器元数据
type adapterMetadata struct {
Name string `json:"name"`
Type string `json:"type"`
Version string `json:"version"`
Description string `json:"description"`
UpdatedAt time.Time `json:"updated_at"`
}
// NewAdapterService 创建适配器服务
func NewAdapterService() AdapterService {
service := &AdapterServiceImpl{
factories: make(map[string]AdapterFactory),
configs: make(map[string]*adapterConfig),
activeAdapters: make(map[string]adapter.DataSourceAdapter),
metadata: make(map[string]*adapterMetadata),
}
// 注册内置适配器
service.registerBuiltinAdapters()
return service
}
// registerBuiltinAdapters 注册内置适配器
func (s *AdapterServiceImpl) registerBuiltinAdapters() {
// 注册Tushare适配器
s.RegisterAdapter("tushare", func() adapter.DataSourceAdapter {
return tushare.NewAdapter()
})
// 设置Tushare元数据
s.metadata["tushare"] = &adapterMetadata{
Name: "tushare",
Type: "http",
Version: "1.0.0",
Description: "Tushare Pro 金融数据接口",
UpdatedAt: time.Now(),
}
// 默认配置
s.configs["tushare"] = &adapterConfig{
Enabled: true,
Config: map[string]string{
"token": "",
"base_url": "https://api.tushare.pro",
},
}
// 预留Wind适配器
s.metadata["wind"] = &adapterMetadata{
Name: "wind",
Type: "ws",
Version: "1.0.0",
Description: "Wind 金融终端接口(预留)",
UpdatedAt: time.Now(),
}
s.configs["wind"] = &adapterConfig{
Enabled: false,
Config: map[string]string{
"host": "localhost",
"port": "8081",
},
}
}
// GetAdapterList 获取适配器列表
func (s *AdapterServiceImpl) GetAdapterList(ctx context.Context) (*api.AdapterListData, error) {
s.mu.RLock()
defer s.mu.RUnlock()
adapters := make([]api.AdapterInfo, 0, len(s.metadata))
for name, meta := range s.metadata {
cfg, ok := s.configs[name]
if !ok {
cfg = &adapterConfig{Enabled: false, Config: make(map[string]string)}
}
status := api.AdapterStatusDisabled
if cfg.Enabled {
status = api.AdapterStatusStandby
// 检查是否是激活状态
if _, active := s.activeAdapters[name]; active {
status = api.AdapterStatusActive
}
}
adapters = append(adapters, api.AdapterInfo{
Name: meta.Name,
Type: meta.Type,
Version: meta.Version,
Description: meta.Description,
Status: status,
Config: cfg.Config,
UpdatedAt: meta.UpdatedAt,
})
}
return &api.AdapterListData{
Adapters: adapters,
}, nil
}
// ToggleAdapter 启用/禁用适配器
func (s *AdapterServiceImpl) ToggleAdapter(ctx context.Context, req *api.AdapterToggleRequest) error {
s.mu.Lock()
defer s.mu.Unlock()
cfg, ok := s.configs[req.Name]
if !ok {
return fmt.Errorf("adapter not found: %s", req.Name)
}
cfg.Enabled = req.Enable
// 如果禁用,关闭适配器连接
if !req.Enable {
if adapter, ok := s.activeAdapters[req.Name]; ok {
adapter.Close()
delete(s.activeAdapters, req.Name)
}
}
// 更新元数据
if meta, ok := s.metadata[req.Name]; ok {
meta.UpdatedAt = time.Now()
}
return nil
}
// UpdateAdapterConfig 更新适配器配置
func (s *AdapterServiceImpl) UpdateAdapterConfig(ctx context.Context, req *api.AdapterConfigUpdateRequest) error {
s.mu.Lock()
defer s.mu.Unlock()
cfg, ok := s.configs[req.Name]
if !ok {
return fmt.Errorf("adapter not found: %s", req.Name)
}
// 更新配置
for k, v := range req.Config {
cfg.Config[k] = v
}
// 如果适配器已激活,重新连接
if adapter, ok := s.activeAdapters[req.Name]; ok {
adapter.Close()
delete(s.activeAdapters, req.Name)
// 如果启用状态,重新连接
if cfg.Enabled {
if err := s.connectAdapter(req.Name); err != nil {
return fmt.Errorf("failed to reconnect adapter: %w", err)
}
}
}
// 更新元数据
if meta, ok := s.metadata[req.Name]; ok {
meta.UpdatedAt = time.Now()
}
return nil
}
// GetActiveAdapter 获取当前激活的适配器
func (s *AdapterServiceImpl) GetActiveAdapter(assetClass string) (adapter.DataSourceAdapter, error) {
s.mu.RLock()
defer s.mu.RUnlock()
// 根据资产类别获取配置
// 这里简化处理,实际应该从配置服务获取
adapterName := "tushare"
if assetClass == "futures" {
adapterName = "tushare"
}
// 检查是否已有激活的实例
if adapter, ok := s.activeAdapters[adapterName]; ok {
return adapter, nil
}
return nil, fmt.Errorf("no active adapter for %s", assetClass)
}
// GetAvailableAdapters 获取所有可用的适配器名称
func (s *AdapterServiceImpl) GetAvailableAdapters() []string {
s.mu.RLock()
defer s.mu.RUnlock()
names := make([]string, 0, len(s.metadata))
for name, meta := range s.metadata {
// 只返回有工厂的适配器(已实现的)
if _, ok := s.factories[name]; ok {
names = append(names, fmt.Sprintf("%s|%s", name, meta.Description))
}
}
return names
}
// RegisterAdapter 注册适配器
func (s *AdapterServiceImpl) RegisterAdapter(name string, factory AdapterFactory) {
s.mu.Lock()
defer s.mu.Unlock()
s.factories[name] = factory
}
// connectAdapter 连接适配器
func (s *AdapterServiceImpl) connectAdapter(name string) error {
factory, ok := s.factories[name]
if !ok {
return fmt.Errorf("adapter factory not found: %s", name)
}
cfg, ok := s.configs[name]
if !ok {
return fmt.Errorf("adapter config not found: %s", name)
}
adapter := factory()
if err := adapter.Connect(cfg.Config); err != nil {
return err
}
s.activeAdapters[name] = adapter
return nil
}
// HealthCheck 适配器健康检查
func (s *AdapterServiceImpl) HealthCheck(name string) error {
s.mu.RLock()
defer s.mu.RUnlock()
adapter, ok := s.activeAdapters[name]
if !ok {
return fmt.Errorf("adapter not active: %s", name)
}
return adapter.HealthCheck()
}