feat: 完成了连接, 断开连接
update: 慢慢过渡到 css-in-js refactory: 新建连接改为 dialog wip: 没找到合适和适应的状态管理方便全局状态管理
This commit is contained in:
@ -28,6 +28,7 @@ func Init(ctx context.Context) error {
|
||||
register("/api/connection/create", handler.ConnectionCreate)
|
||||
register("/api/connection/list", handler.ConnectionList)
|
||||
register("/api/connection/connect", handler.ConnectionConnect)
|
||||
register("/api/connection/disconnect", handler.ConnectionDisconnect)
|
||||
register("/api/connection/buckets", handler.ConnectionBuckets)
|
||||
|
||||
return nil
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"github.com/loveuer/nf-disk/internal/api"
|
||||
"github.com/loveuer/nf-disk/internal/db"
|
||||
"github.com/loveuer/nf-disk/internal/manager"
|
||||
"github.com/loveuer/nf-disk/internal/model"
|
||||
"github.com/loveuer/nf-disk/internal/tool"
|
||||
"github.com/loveuer/nf-disk/ndh"
|
||||
@ -23,9 +24,12 @@ func NewApp() *App {
|
||||
|
||||
func (a *App) Init(ctx context.Context) {
|
||||
log.Info("app init!!!")
|
||||
|
||||
a.ctx = ctx
|
||||
|
||||
tool.Must(db.Init(ctx, "sqlite::memory", db.OptSqliteByMem(nil)))
|
||||
tool.Must(model.Init(db.Default.Session()))
|
||||
tool.Must(manager.Init(ctx))
|
||||
tool.Must(api.Init(ctx))
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/loveuer/nf-disk/internal/db"
|
||||
"github.com/loveuer/nf-disk/internal/manager"
|
||||
"github.com/loveuer/nf-disk/internal/model"
|
||||
"github.com/loveuer/nf-disk/internal/s3"
|
||||
"github.com/loveuer/nf-disk/ndh"
|
||||
"github.com/pkg/errors"
|
||||
"gorm.io/gorm"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func ConnectionTest(c *ndh.Ctx) error {
|
||||
@ -80,7 +80,7 @@ func ConnectionCreate(c *ndh.Ctx) error {
|
||||
return c.Send500(err.Error(), "创建连接失败(1)")
|
||||
}
|
||||
|
||||
if err = manager.Register(connection, client); err != nil {
|
||||
if err = manager.Manager.Register(connection, client); err != nil {
|
||||
return c.Send500(err.Error(), "创建连接失败(2)")
|
||||
}
|
||||
|
||||
@ -108,6 +108,18 @@ func ConnectionList(c *ndh.Ctx) error {
|
||||
return err
|
||||
}
|
||||
|
||||
listMap := lo.SliceToMap(list, func(item *model.Connection) (uint64, *model.Connection) {
|
||||
return item.Id, item
|
||||
})
|
||||
|
||||
manager.Manager.Map(func(c *model.Connection, s *s3.Client) error {
|
||||
if item, ok := listMap[c.Id]; ok {
|
||||
item.Active = true
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return c.Send200(map[string]any{"list": list})
|
||||
}
|
||||
|
||||
@ -119,27 +131,49 @@ func ConnectionConnect(c *ndh.Ctx) error {
|
||||
var (
|
||||
err error
|
||||
req = new(Req)
|
||||
conn = new(model.Connection)
|
||||
client *s3.Client
|
||||
)
|
||||
|
||||
if err = c.ReqParse(req); err != nil {
|
||||
return c.Send400(nil, "参数错误")
|
||||
return c.Send400(req)
|
||||
}
|
||||
|
||||
if err = db.Default.Session().Take(conn, req.Id).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return c.Send400(c, "不存在的连接")
|
||||
}
|
||||
|
||||
return c.Send500(nil)
|
||||
conn := &model.Connection{Id: req.Id}
|
||||
if err = conn.Get(db.Default.Session(), c); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if client, err = s3.New(c.Context(), conn.Endpoint, conn.Access, conn.Key); err != nil {
|
||||
return c.Send500(err.Error())
|
||||
return c.Send500(err.Error(), "连接失败")
|
||||
}
|
||||
|
||||
if err = manager.Register(conn, client); err != nil {
|
||||
if err = manager.Manager.Register(conn, client); err != nil {
|
||||
return c.Send500(err.Error(), "连接失败")
|
||||
}
|
||||
|
||||
return c.Send200(conn, "连接成功")
|
||||
}
|
||||
|
||||
func ConnectionDisconnect(c *ndh.Ctx) error {
|
||||
type Req struct {
|
||||
Id uint64 `json:"id"`
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
req = new(Req)
|
||||
)
|
||||
|
||||
if err = c.ReqParse(req); err != nil {
|
||||
return c.Send400(req)
|
||||
}
|
||||
|
||||
conn := &model.Connection{Id: req.Id}
|
||||
if err = conn.Get(db.Default.Session(), c); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = manager.Manager.UnRegister(conn.Id); err != nil {
|
||||
return c.Send500(err.Error())
|
||||
}
|
||||
|
||||
@ -153,13 +187,27 @@ func ConnectionBuckets(c *ndh.Ctx) error {
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
req = new(Req)
|
||||
err error
|
||||
req = new(Req)
|
||||
client *s3.Client
|
||||
buckets []*s3.ListBucketRes
|
||||
)
|
||||
|
||||
if err = c.ReqParse(req); err != nil {
|
||||
return c.Send400(nil, "参数错误")
|
||||
}
|
||||
|
||||
panic("implement me: ConnectionBuckets")
|
||||
if _, client, err = manager.Manager.Use(req.Id); err != nil {
|
||||
if errors.Is(err, manager.ErrNotFound) {
|
||||
return c.Send400(nil, "所选连接未激活")
|
||||
}
|
||||
|
||||
return c.Send500(err.Error())
|
||||
}
|
||||
|
||||
if buckets, err = client.ListBucket(c.Context()); err != nil {
|
||||
return c.Send500(err.Error())
|
||||
}
|
||||
|
||||
return c.Send200(map[string]any{"list": buckets})
|
||||
}
|
||||
|
21
internal/handler/item.go
Normal file
21
internal/handler/item.go
Normal file
@ -0,0 +1,21 @@
|
||||
package handler
|
||||
|
||||
import "github.com/loveuer/nf-disk/ndh"
|
||||
|
||||
func ListItem(c *ndh.Ctx) error {
|
||||
type Req struct {
|
||||
Id uint64 `json:"id"`
|
||||
Bucket string `json:"bucket"`
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
req = new(Req)
|
||||
)
|
||||
|
||||
if err = c.ReqParse(req); err != nil {
|
||||
return c.Send400(err.Error())
|
||||
}
|
||||
|
||||
panic("implement me!!!")
|
||||
}
|
7
internal/manager/error.go
Normal file
7
internal/manager/error.go
Normal file
@ -0,0 +1,7 @@
|
||||
package manager
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrNotFound = errors.New("not found")
|
||||
)
|
@ -5,14 +5,71 @@ import (
|
||||
"github.com/loveuer/nf-disk/internal/model"
|
||||
"github.com/loveuer/nf-disk/internal/s3"
|
||||
"github.com/loveuer/nf/nft/log"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type client struct {
|
||||
conn *model.Connection
|
||||
client *s3.Client
|
||||
}
|
||||
|
||||
type manager struct {
|
||||
sync.Mutex
|
||||
clients map[uint64]*client
|
||||
}
|
||||
|
||||
var (
|
||||
Manager *manager
|
||||
)
|
||||
|
||||
func Init(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Register(m *model.Connection, c *s3.Client) error {
|
||||
log.Debug("manager: register connection-client: id = %d, name = %s", m.Id, m.Name)
|
||||
Manager = &manager{
|
||||
clients: make(map[uint64]*client),
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *manager) Register(c *model.Connection, s *s3.Client) error {
|
||||
log.Debug("manager: register connection-client: id = %d, name = %s", c.Id, c.Name)
|
||||
|
||||
Manager.Lock()
|
||||
defer Manager.Unlock()
|
||||
Manager.clients[c.Id] = &client{conn: c, client: s}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *manager) UnRegister(id uint64) error {
|
||||
Manager.Lock()
|
||||
defer Manager.Unlock()
|
||||
c, ok := m.clients[id]
|
||||
if !ok {
|
||||
return ErrNotFound
|
||||
}
|
||||
|
||||
log.Debug("manager: register connection-client: id = %d, name = %s", c.conn, c.conn.Name)
|
||||
|
||||
delete(m.clients, id)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *manager) Map(fn func(*model.Connection, *s3.Client) error) error {
|
||||
for _, item := range m.clients {
|
||||
if err := fn(item.conn, item.client); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *manager) Use(id uint64) (*model.Connection, *s3.Client, error) {
|
||||
c, ok := m.clients[id]
|
||||
if !ok {
|
||||
return nil, nil, ErrNotFound
|
||||
}
|
||||
|
||||
return c.conn, c.client, nil
|
||||
}
|
||||
|
@ -1,6 +1,10 @@
|
||||
package model
|
||||
|
||||
import "gorm.io/gorm"
|
||||
import (
|
||||
"errors"
|
||||
"github.com/loveuer/nf-disk/ndh"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Connection struct {
|
||||
Id uint64 `json:"id" gorm:"primaryKey;column:id"`
|
||||
@ -11,8 +15,22 @@ type Connection struct {
|
||||
Endpoint string `json:"endpoint" gorm:"column:endpoint"`
|
||||
Access string `json:"access" gorm:"column:access"`
|
||||
Key string `json:"key" gorm:"column:key"`
|
||||
|
||||
Active bool `json:"active" gorm:"-"`
|
||||
}
|
||||
|
||||
func (c *Connection) Create(tx *gorm.DB) error {
|
||||
return tx.Create(c).Error
|
||||
}
|
||||
|
||||
func (c *Connection) Get(tx *gorm.DB, ctx *ndh.Ctx) error {
|
||||
if err := tx.Take(c, c.Id).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return ctx.Send400(err.Error())
|
||||
}
|
||||
|
||||
return ctx.Send500(err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
37
internal/s3/list.go
Normal file
37
internal/s3/list.go
Normal file
@ -0,0 +1,37 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type ListBucketRes struct {
|
||||
CreatedAt int64
|
||||
Name string
|
||||
}
|
||||
|
||||
func (c *Client) ListBucket(ctx context.Context) ([]*ListBucketRes, error) {
|
||||
var (
|
||||
err error
|
||||
input = &s3.ListBucketsInput{
|
||||
MaxBuckets: aws.Int32(100),
|
||||
}
|
||||
output *s3.ListBucketsOutput
|
||||
)
|
||||
|
||||
if output, err = c.client.ListBuckets(ctx, input); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := lo.Map(
|
||||
output.Buckets,
|
||||
func(item types.Bucket, index int) *ListBucketRes {
|
||||
return &ListBucketRes{CreatedAt: item.CreationDate.UnixMilli(), Name: *item.Name}
|
||||
},
|
||||
)
|
||||
|
||||
return res, nil
|
||||
}
|
Reference in New Issue
Block a user