diff --git a/cmd/edge-api/main.go b/cmd/edge-api/main.go index fc0970c2..476b1070 100644 --- a/cmd/edge-api/main.go +++ b/cmd/edge-api/main.go @@ -4,6 +4,7 @@ import ( "github.com/TeaOSLab/EdgeAPI/internal/apis" "github.com/TeaOSLab/EdgeAPI/internal/apps" teaconst "github.com/TeaOSLab/EdgeAPI/internal/const" + _ "github.com/TeaOSLab/EdgeAPI/internal/tasks" _ "github.com/iwind/TeaGo/bootstrap" ) diff --git a/internal/apis/api_node.go b/internal/apis/api_node.go index 4ea6624b..e63abaf5 100644 --- a/internal/apis/api_node.go +++ b/internal/apis/api_node.go @@ -61,6 +61,7 @@ func (this *APINode) listenRPC() error { pb.RegisterOriginServerServiceServer(rpcServer, &services.OriginServerService{}) pb.RegisterHTTPWebServiceServer(rpcServer, &services.HTTPWebService{}) pb.RegisterReverseProxyServiceServer(rpcServer, &services.ReverseProxyService{}) + pb.RegisterHTTPGzipServiceServer(rpcServer, &services.HTTPGzipService{}) err = rpcServer.Serve(listener) if err != nil { return errors.New("[API]start rpc failed: " + err.Error()) diff --git a/internal/db/models/http_gzip_dao.go b/internal/db/models/http_gzip_dao.go new file mode 100644 index 00000000..8ee5772b --- /dev/null +++ b/internal/db/models/http_gzip_dao.go @@ -0,0 +1,133 @@ +package models + +import ( + "encoding/json" + "errors" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared" + _ "github.com/go-sql-driver/mysql" + "github.com/iwind/TeaGo/Tea" + "github.com/iwind/TeaGo/dbs" + "github.com/iwind/TeaGo/types" +) + +const ( + HTTPGzipStateEnabled = 1 // 已启用 + HTTPGzipStateDisabled = 0 // 已禁用 +) + +type HTTPGzipDAO dbs.DAO + +func NewHTTPGzipDAO() *HTTPGzipDAO { + return dbs.NewDAO(&HTTPGzipDAO{ + DAOObject: dbs.DAOObject{ + DB: Tea.Env, + Table: "edgeHTTPGzips", + Model: new(HTTPGzip), + PkName: "id", + }, + }).(*HTTPGzipDAO) +} + +var SharedHTTPGzipDAO = NewHTTPGzipDAO() + +// 启用条目 +func (this *HTTPGzipDAO) EnableHTTPGzip(id int64) error { + _, err := this.Query(). + Pk(id). + Set("state", HTTPGzipStateEnabled). + Update() + return err +} + +// 禁用条目 +func (this *HTTPGzipDAO) DisableHTTPGzip(id int64) error { + _, err := this.Query(). + Pk(id). + Set("state", HTTPGzipStateDisabled). + Update() + return err +} + +// 查找启用中的条目 +func (this *HTTPGzipDAO) FindEnabledHTTPGzip(id int64) (*HTTPGzip, error) { + result, err := this.Query(). + Pk(id). + Attr("state", HTTPGzipStateEnabled). + Find() + if result == nil { + return nil, err + } + return result.(*HTTPGzip), err +} + +// 组合配置 +func (this *HTTPGzipDAO) ComposeGzipConfig(gzipId int64) (*serverconfigs.HTTPGzipConfig, error) { + gzip, err := this.FindEnabledHTTPGzip(gzipId) + if err != nil { + return nil, err + } + + if gzip == nil { + return nil, nil + } + + config := &serverconfigs.HTTPGzipConfig{} + config.Id = int64(gzip.Id) + config.IsOn = gzip.IsOn == 1 + if len(gzip.MinLength) > 0 && gzip.MinLength != "null" { + minLengthConfig := &shared.SizeCapacity{} + err = json.Unmarshal([]byte(gzip.MinLength), minLengthConfig) + if err != nil { + return nil, err + } + config.MinLength = minLengthConfig + } + if len(gzip.MaxLength) > 0 && gzip.MaxLength != "null" { + maxLengthConfig := &shared.SizeCapacity{} + err = json.Unmarshal([]byte(gzip.MaxLength), maxLengthConfig) + if err != nil { + return nil, err + } + config.MaxLength = maxLengthConfig + } + config.Level = types.Int8(gzip.Level) + return config, nil +} + +// 创建Gzip +func (this *HTTPGzipDAO) CreateGzip(level int, minLengthJSON []byte, maxLengthJSON []byte) (int64, error) { + op := NewHTTPGzipOperator() + op.State = HTTPGzipStateEnabled + op.IsOn = true + op.Level = level + if len(minLengthJSON) > 0 { + op.MinLength = string(minLengthJSON) + } + if len(maxLengthJSON) > 0 { + op.MaxLength = string(maxLengthJSON) + } + _, err := this.Save(op) + if err != nil { + return 0, err + } + return types.Int64(op.Id), nil +} + +// 修改Gzip +func (this *HTTPGzipDAO) UpdateGzip(gzipId int64, level int, minLengthJSON []byte, maxLengthJSON []byte) error { + if gzipId <= 0 { + return errors.New("invalid gzipId") + } + op := NewHTTPGzipOperator() + op.Id = gzipId + op.Level = level + if len(minLengthJSON) > 0 { + op.MinLength = string(minLengthJSON) + } + if len(maxLengthJSON) > 0 { + op.MaxLength = string(maxLengthJSON) + } + _, err := this.Save(op) + return err +} diff --git a/internal/db/models/http_gzip_dao_test.go b/internal/db/models/http_gzip_dao_test.go new file mode 100644 index 00000000..97c24b56 --- /dev/null +++ b/internal/db/models/http_gzip_dao_test.go @@ -0,0 +1,5 @@ +package models + +import ( + _ "github.com/go-sql-driver/mysql" +) diff --git a/internal/db/models/http_gzip_model.go b/internal/db/models/http_gzip_model.go new file mode 100644 index 00000000..9fe1dcd4 --- /dev/null +++ b/internal/db/models/http_gzip_model.go @@ -0,0 +1,30 @@ +package models + +// Gzip配置 +type HTTPGzip struct { + Id uint32 `field:"id"` // ID + AdminId uint32 `field:"adminId"` // 管理员ID + UserId uint32 `field:"userId"` // 用户ID + IsOn uint8 `field:"isOn"` // 是否启用 + Level uint32 `field:"level"` // 压缩级别 + MinLength string `field:"minLength"` // 可压缩最小值 + MaxLength string `field:"maxLength"` // 可压缩最大值 + State uint8 `field:"state"` // 状态 + CreatedAt uint32 `field:"createdAt"` // 创建时间 +} + +type HTTPGzipOperator struct { + Id interface{} // ID + AdminId interface{} // 管理员ID + UserId interface{} // 用户ID + IsOn interface{} // 是否启用 + Level interface{} // 压缩级别 + MinLength interface{} // 可压缩最小值 + MaxLength interface{} // 可压缩最大值 + State interface{} // 状态 + CreatedAt interface{} // 创建时间 +} + +func NewHTTPGzipOperator() *HTTPGzipOperator { + return &HTTPGzipOperator{} +} diff --git a/internal/db/models/http_gzip_model_ext.go b/internal/db/models/http_gzip_model_ext.go new file mode 100644 index 00000000..3c57cf5d --- /dev/null +++ b/internal/db/models/http_gzip_model_ext.go @@ -0,0 +1,26 @@ +package models + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared" +) + +// 解析最小长度 +func (this *HTTPGzip) DecodeMinLength() (*shared.SizeCapacity, error) { + if len(this.MinLength) == 0 { + return nil, nil + } + capacity := &shared.SizeCapacity{} + err := json.Unmarshal([]byte(this.MinLength), capacity) + return capacity, err +} + +// 解析最大长度 +func (this *HTTPGzip) DecodeMaxLength() (*shared.SizeCapacity, error) { + if len(this.MaxLength) == 0 { + return nil, nil + } + capacity := &shared.SizeCapacity{} + err := json.Unmarshal([]byte(this.MaxLength), capacity) + return capacity, err +} diff --git a/internal/db/models/http_web_dao.go b/internal/db/models/http_web_dao.go index 9b931a1d..ca035c66 100644 --- a/internal/db/models/http_web_dao.go +++ b/internal/db/models/http_web_dao.go @@ -60,7 +60,7 @@ func (this *HTTPWebDAO) FindEnabledHTTPWeb(id int64) (*HTTPWeb, error) { } // 组合配置 -func (this *HTTPWebDAO) ComposeWebConfig(webId int64) (*serverconfigs.WebConfig, error) { +func (this *HTTPWebDAO) ComposeWebConfig(webId int64) (*serverconfigs.HTTPWebConfig, error) { web, err := SharedHTTPWebDAO.FindEnabledHTTPWeb(webId) if err != nil { return nil, err @@ -68,9 +68,24 @@ func (this *HTTPWebDAO) ComposeWebConfig(webId int64) (*serverconfigs.WebConfig, if web == nil { return nil, nil } - config := &serverconfigs.WebConfig{} + config := &serverconfigs.HTTPWebConfig{} + config.Id = webId config.IsOn = web.IsOn == 1 config.Root = web.Root + + // gzip + if web.GzipId > 0 { + gzipConfig, err := SharedHTTPGzipDAO.ComposeGzipConfig(int64(web.GzipId)) + if err != nil { + return nil, err + } + config.Gzip = gzipConfig + } + + // TODO charset + + // TODO 更多配置 + return config, nil } @@ -95,8 +110,37 @@ func (this *HTTPWebDAO) UpdateWeb(webId int64, root string) error { op.Id = webId op.Root = root _, err := this.Save(op) + if err != nil { + return err + } - // TODO 更新所有使用此Web配置的服务 - - return err + return this.NotifyUpdating(webId) +} + +// 修改Gzip配置 +func (this *HTTPWebDAO) UpdateWebGzip(webId int64, gzipId int64) error { + if webId <= 0 { + return errors.New("invalid webId") + } + op := NewHTTPWebOperator() + op.Id = webId + op.GzipId = gzipId + _, err := this.Save(op) + if err != nil { + return err + } + + return this.NotifyUpdating(webId) +} + +// 通知更新 +func (this *HTTPWebDAO) NotifyUpdating(webId int64) error { + err := SharedServerDAO.UpdateServerIsUpdatingWithWebId(webId) + if err != nil { + return err + } + + // TODO 更新所有使用此Web配置的Location所在服务 + + return nil } diff --git a/internal/db/models/http_web_model.go b/internal/db/models/http_web_model.go index c2ae2731..4d6d10a6 100644 --- a/internal/db/models/http_web_model.go +++ b/internal/db/models/http_web_model.go @@ -10,6 +10,7 @@ type HTTPWeb struct { State uint8 `field:"state"` // 状态 CreatedAt uint32 `field:"createdAt"` // 创建时间 Root string `field:"root"` // 资源根目录 + GzipId uint32 `field:"gzipId"` // Gzip配置 } type HTTPWebOperator struct { @@ -21,6 +22,7 @@ type HTTPWebOperator struct { State interface{} // 状态 CreatedAt interface{} // 创建时间 Root interface{} // 资源根目录 + GzipId interface{} // Gzip配置 } func NewHTTPWebOperator() *HTTPWebOperator { diff --git a/internal/db/models/origin_server_dao.go b/internal/db/models/origin_server_dao.go index de054f6e..31da36db 100644 --- a/internal/db/models/origin_server_dao.go +++ b/internal/db/models/origin_server_dao.go @@ -118,7 +118,7 @@ func (this *OriginServerDAO) ComposeOriginConfig(originId int64) (*serverconfigs } } - connTimeout := shared.TimeDuration{} + connTimeout := &shared.TimeDuration{} if len(origin.ConnTimeout) > 0 && origin.ConnTimeout != "null" { err = json.Unmarshal([]byte(origin.ConnTimeout), &connTimeout) if err != nil { @@ -126,7 +126,7 @@ func (this *OriginServerDAO) ComposeOriginConfig(originId int64) (*serverconfigs } } - readTimeout := shared.TimeDuration{} + readTimeout := &shared.TimeDuration{} if len(origin.ReadTimeout) > 0 && origin.ReadTimeout != "null" { err = json.Unmarshal([]byte(origin.ReadTimeout), &readTimeout) if err != nil { @@ -134,7 +134,7 @@ func (this *OriginServerDAO) ComposeOriginConfig(originId int64) (*serverconfigs } } - idleTimeout := shared.TimeDuration{} + idleTimeout := &shared.TimeDuration{} if len(origin.IdleTimeout) > 0 && origin.IdleTimeout != "null" { err = json.Unmarshal([]byte(origin.IdleTimeout), &idleTimeout) if err != nil { diff --git a/internal/db/models/origin_server_dao_test.go b/internal/db/models/origin_server_dao_test.go index 97c24b56..2c8ab4a6 100644 --- a/internal/db/models/origin_server_dao_test.go +++ b/internal/db/models/origin_server_dao_test.go @@ -2,4 +2,13 @@ package models import ( _ "github.com/go-sql-driver/mysql" + "testing" ) + +func TestOriginServerDAO_ComposeOriginConfig(t *testing.T) { + config, err := SharedOriginServerDAO.ComposeOriginConfig(1) + if err != nil { + t.Fatal(err) + } + t.Log(config) +} diff --git a/internal/db/models/reverse_proxy_dao.go b/internal/db/models/reverse_proxy_dao.go index faf82eea..ae1dd428 100644 --- a/internal/db/models/reverse_proxy_dao.go +++ b/internal/db/models/reverse_proxy_dao.go @@ -88,7 +88,7 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(reverseProxyId int64) (*s return nil, err } for _, originConfig := range originConfigs { - newOriginConfig, err := SharedOriginServerDAO.ComposeOriginConfig(int64(originConfig.Id)) + newOriginConfig, err := SharedOriginServerDAO.ComposeOriginConfig(originConfig.Id) if err != nil { return nil, err } @@ -99,7 +99,7 @@ func (this *ReverseProxyDAO) ComposeReverseProxyConfig(reverseProxyId int64) (*s } if len(reverseProxy.BackupOrigins) > 0 && reverseProxy.BackupOrigins != "null" { - originConfigs := []*OriginServer{} + originConfigs := []*serverconfigs.OriginServerConfig{} err = json.Unmarshal([]byte(reverseProxy.BackupOrigins), &originConfigs) if err != nil { return nil, err @@ -195,3 +195,12 @@ func (this *ReverseProxyDAO) UpdateReverseProxyBackupOrigins(reverseProxyId int6 return err } + +// 修改是否启用 +func (this *ReverseProxyDAO) UpdateReverseProxyIsOn(reverseProxyId int64, isOn bool) error { + _, err := this.Query(). + Pk(reverseProxyId). + Set("isOn", isOn). + Update() + return err +} diff --git a/internal/db/models/server_dao.go b/internal/db/models/server_dao.go index 1d237530..1bb304b4 100644 --- a/internal/db/models/server_dao.go +++ b/internal/db/models/server_dao.go @@ -283,6 +283,28 @@ func (this *ServerDAO) UpdateServerWeb(serverId int64, webId int64) error { return this.RenewServerConfig(serverId) } +// 初始化Web配置 +func (this *ServerDAO) InitServerWeb(serverId int64) (int64, error) { + if serverId <= 0 { + return 0, errors.New("serverId should not be smaller than 0") + } + + webId, err := SharedHTTPWebDAO.CreateWeb("") + if err != nil { + return 0, err + } + + _, err = this.Query(). + Pk(serverId). + Set("webId", webId). + Update() + if err != nil { + return 0, err + } + + return webId, nil +} + // 修改ServerNames配置 func (this *ServerDAO) UpdateServerNames(serverId int64, config []byte) error { if serverId <= 0 { @@ -503,6 +525,40 @@ func (this *ServerDAO) FindReverseProxyConfig(serverId int64) (*serverconfigs.Re return config, err } +// 查找需要更新的Server +func (this *ServerDAO) FindUpdatingServerIds() (serverIds []int64, err error) { + ones, err := this.Query(). + State(ServerStateEnabled). + Attr("isUpdating", true). + ResultPk(). + FindAll() + if err != nil { + return nil, err + } + for _, one := range ones { + serverIds = append(serverIds, int64(one.(*Server).Id)) + } + return +} + +// 修改服务是否需要更新 +func (this *ServerDAO) UpdateServerIsUpdating(serverId int64, isUpdating bool) error { + _, err := this.Query(). + Pk(serverId). + Set("isUpdating", isUpdating). + Update() + return err +} + +// 更新所有Web相关的处于更新状态 +func (this *ServerDAO) UpdateServerIsUpdatingWithWebId(webId int64) error { + _, err := this.Query(). + Attr("webId", webId). + Set("isUpdating", true). + Update() + return err +} + // 生成唯一ID func (this *ServerDAO) genUniqueId() (string, error) { for { diff --git a/internal/db/models/server_model.go b/internal/db/models/server_model.go index 7a19cfb4..6ff4910e 100644 --- a/internal/db/models/server_model.go +++ b/internal/db/models/server_model.go @@ -26,6 +26,7 @@ type Server struct { ExcludeNodes string `field:"excludeNodes"` // 节点排除条件 Version uint32 `field:"version"` // 版本号 CreatedAt uint32 `field:"createdAt"` // 创建时间 + IsUpdating uint8 `field:"isUpdating"` // 是否正在更新 State uint8 `field:"state"` // 状态 } @@ -54,6 +55,7 @@ type ServerOperator struct { ExcludeNodes interface{} // 节点排除条件 Version interface{} // 版本号 CreatedAt interface{} // 创建时间 + IsUpdating interface{} // 是否正在更新 State interface{} // 状态 } diff --git a/internal/rpc/services/service_http_web.go b/internal/rpc/services/service_http_web.go index 8c9e909e..0e093691 100644 --- a/internal/rpc/services/service_http_web.go +++ b/internal/rpc/services/service_http_web.go @@ -45,7 +45,9 @@ func (this *HTTPWebService) FindEnabledHTTPWeb(ctx context.Context, req *pb.Find result := &pb.HTTPWeb{} result.Id = int64(web.Id) + result.IsOn = web.IsOn == 1 result.Root = web.Root + result.GzipId = int64(web.GzipId) return &pb.FindEnabledHTTPWebResponse{Web: result}, nil } @@ -64,3 +66,19 @@ func (this *HTTPWebService) UpdateHTTPWeb(ctx context.Context, req *pb.UpdateHTT return &pb.UpdateHTTPWebResponse{}, nil } + +// 修改Gzip配置 +func (this *HTTPWebService) UpdateHTTPWebGzip(ctx context.Context, req *pb.UpdateHTTPWebGzipRequest) (*pb.UpdateHTTPWebGzipResponse, error) { + // 校验请求 + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + err = models.SharedHTTPWebDAO.UpdateWebGzip(req.WebId, req.GzipId) + if err != nil { + return nil, err + } + + return &pb.UpdateHTTPWebGzipResponse{}, nil +} diff --git a/internal/rpc/services/service_reverse_proxy.go b/internal/rpc/services/service_reverse_proxy.go index e6619ffc..c4761667 100644 --- a/internal/rpc/services/service_reverse_proxy.go +++ b/internal/rpc/services/service_reverse_proxy.go @@ -120,3 +120,19 @@ func (this *ReverseProxyService) UpdateReverseProxyBackupOrigins(ctx context.Con return &pb.UpdateReverseProxyBackupOriginsResponse{}, nil } + +// 修改是否启用 +func (this *ReverseProxyService) UpdateReverseProxyIsOn(ctx context.Context, req *pb.UpdateReverseProxyIsOnRequest) (*pb.UpdateReverseProxyIsOnResponse, error) { + // 校验请求 + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + err = models.SharedReverseProxyDAO.UpdateReverseProxyIsOn(req.ReverseProxyId, req.IsOn) + if err != nil { + return nil, err + } + + return &pb.UpdateReverseProxyIsOnResponse{}, nil +} diff --git a/internal/rpc/services/service_server.go b/internal/rpc/services/service_server.go index cb85565f..a9299c01 100644 --- a/internal/rpc/services/service_server.go +++ b/internal/rpc/services/service_server.go @@ -426,6 +426,12 @@ func (this *ServerService) ListEnabledServers(ctx context.Context, req *pb.ListE Config: []byte(server.Config), Name: server.Name, Description: server.Description, + HttpJSON: []byte(server.Http), + HttpsJSON: []byte(server.Https), + TcpJSON: []byte(server.Tcp), + TlsJSON: []byte(server.Tls), + UnixJSON: []byte(server.Unix), + UdpJSON: []byte(server.Udp), IncludeNodes: []byte(server.IncludeNodes), ExcludeNodes: []byte(server.ExcludeNodes), CreatedAt: int64(server.CreatedAt), @@ -497,6 +503,7 @@ func (this *ServerService) FindEnabledServer(ctx context.Context, req *pb.FindEn Name: server.Name, Description: server.Description, Config: []byte(server.Config), + ServerNamesJON: []byte(server.ServerNames), HttpJSON: []byte(server.Http), HttpsJSON: []byte(server.Https), TcpJSON: []byte(server.Tcp), @@ -532,7 +539,7 @@ func (this *ServerService) FindEnabledServerType(ctx context.Context, req *pb.Fi } // 查找反向代理设置 -func (this *ServerService) FindServerReverseProxy(ctx context.Context, req *pb.FindServerReverseProxyRequest) (*pb.FindServerReverseProxyResponse, error) { +func (this *ServerService) FindServerReverseProxyConfig(ctx context.Context, req *pb.FindServerReverseProxyConfigRequest) (*pb.FindServerReverseProxyConfigResponse, error) { _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) if err != nil { return nil, err @@ -544,12 +551,27 @@ func (this *ServerService) FindServerReverseProxy(ctx context.Context, req *pb.F } if reverseProxy == nil { - return &pb.FindServerReverseProxyResponse{Config: nil}, nil + return &pb.FindServerReverseProxyConfigResponse{Config: nil}, nil } configData, err := json.Marshal(reverseProxy) if err != nil { return nil, err } - return &pb.FindServerReverseProxyResponse{Config: configData}, nil + return &pb.FindServerReverseProxyConfigResponse{Config: configData}, nil +} + +// 初始化Web设置 +func (this *ServerService) InitServerWeb(ctx context.Context, req *pb.InitServerWebRequest) (*pb.InitServerWebResponse, error) { + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + webId, err := models.SharedServerDAO.InitServerWeb(req.ServerId) + if err != nil { + return nil, err + } + + return &pb.InitServerWebResponse{WebId: webId}, nil } diff --git a/internal/rpc/services/sevice_http_gzip.go b/internal/rpc/services/sevice_http_gzip.go new file mode 100644 index 00000000..a4864953 --- /dev/null +++ b/internal/rpc/services/sevice_http_gzip.go @@ -0,0 +1,109 @@ +package services + +import ( + "context" + "encoding/json" + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils" + "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" + "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared" +) + +type HTTPGzipService struct { +} + +// 创建Gzip配置 +func (this *HTTPGzipService) CreateHTTPGzip(ctx context.Context, req *pb.CreateHTTPGzipRequest) (*pb.CreateHTTPGzipResponse, error) { + // 校验请求 + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + minLengthJSON := []byte{} + if req.MinLength != nil { + minLengthJSON, err = (&shared.SizeCapacity{ + Count: req.MinLength.Count, + Unit: req.MinLength.Unit, + }).AsJSON() + if err != nil { + return nil, err + } + } + + maxLengthJSON := []byte{} + if req.MaxLength != nil { + maxLengthJSON, err = (&shared.SizeCapacity{ + Count: req.MaxLength.Count, + Unit: req.MaxLength.Unit, + }).AsJSON() + if err != nil { + return nil, err + } + } + + gzipId, err := models.SharedHTTPGzipDAO.CreateGzip(int(req.Level), minLengthJSON, maxLengthJSON) + if err != nil { + return nil, err + } + + return &pb.CreateHTTPGzipResponse{GzipId: gzipId}, nil +} + +// 查找Gzip +func (this *HTTPGzipService) FindEnabledHTTPGzipConfig(ctx context.Context, req *pb.FindEnabledGzipConfigRequest) (*pb.FindEnabledGzipConfigResponse, error) { + // 校验请求 + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + config, err := models.SharedHTTPGzipDAO.ComposeGzipConfig(req.GzipId) + if err != nil { + return nil, err + } + + configData, err := json.Marshal(config) + if err != nil { + return nil, err + } + return &pb.FindEnabledGzipConfigResponse{Config: configData}, nil +} + +// 修改Gzip配置 +func (this *HTTPGzipService) UpdateHTTPGzip(ctx context.Context, req *pb.UpdateHTTPGzipRequest) (*pb.UpdateHTTPGzipResponse, error) { + // 校验请求 + _, _, err := rpcutils.ValidateRequest(ctx, rpcutils.UserTypeAdmin) + if err != nil { + return nil, err + } + + minLengthJSON := []byte{} + if req.MinLength != nil { + minLengthJSON, err = (&shared.SizeCapacity{ + Count: req.MinLength.Count, + Unit: req.MinLength.Unit, + }).AsJSON() + if err != nil { + return nil, err + } + } + + maxLengthJSON := []byte{} + if req.MaxLength != nil { + maxLengthJSON, err = (&shared.SizeCapacity{ + Count: req.MaxLength.Count, + Unit: req.MaxLength.Unit, + }).AsJSON() + if err != nil { + return nil, err + } + } + + err = models.SharedHTTPGzipDAO.UpdateGzip(req.GzipId, int(req.Level), minLengthJSON, maxLengthJSON) + if err != nil { + return nil, err + } + + return &pb.UpdateHTTPGzipResponse{}, nil +} diff --git a/internal/tasks/task_server_update.go b/internal/tasks/task_server_update.go new file mode 100644 index 00000000..6061be03 --- /dev/null +++ b/internal/tasks/task_server_update.go @@ -0,0 +1,70 @@ +package tasks + +import ( + "encoding/json" + "github.com/TeaOSLab/EdgeAPI/internal/db/models" + "github.com/iwind/TeaGo/logs" + "time" +) + +// TODO 考虑多个API服务同时运行的冲突 +func init() { + task := &ServerUpdateTask{} + go task.Run() +} + +// 更新服务配置 +type ServerUpdateTask struct { +} + +func (this *ServerUpdateTask) Run() { + ticker := time.NewTicker(1 * time.Second) + for range ticker.C { + this.loop() + } +} + +func (this *ServerUpdateTask) loop() { + serverIds, err := models.SharedServerDAO.FindUpdatingServerIds() + if err != nil { + logs.Println("[ServerUpdateTask]" + err.Error()) + return + } + if len(serverIds) == 0 { + return + } + for _, serverId := range serverIds { + // 查找配置 + config, err := models.SharedServerDAO.ComposeServerConfig(serverId) + if err != nil { + logs.Println("[ServerUpdateTask]" + err.Error()) + continue + } + if config == nil { + err = models.SharedServerDAO.UpdateServerIsUpdating(serverId, false) + if err != nil { + logs.Println("[ServerUpdateTask]" + err.Error()) + continue + } + } + configData, err := json.Marshal(config) + if err != nil { + logs.Println("[ServerUpdateTask]" + err.Error()) + continue + } + + // 修改配置 + err = models.SharedServerDAO.UpdateServerConfig(serverId, configData) + if err != nil { + logs.Println("[ServerUpdateTask]" + err.Error()) + continue + } + + // 修改更新状态 + err = models.SharedServerDAO.UpdateServerIsUpdating(serverId, false) + if err != nil { + logs.Println("[ServerUpdateTask]" + err.Error()) + continue + } + } +}