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
306 lines
7.3 KiB
|
3 months ago
|
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()
|
||
|
|
}
|