Initial commit (code only without large binaries)

This commit is contained in:
robin
2026-02-15 18:58:44 +08:00
commit 35df75498f
9442 changed files with 1495866 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
type DeleteTaskAction struct {
actionutils.ParentAction
}
func (this *DeleteTaskAction) RunPost(params struct {
TaskId int64
}) {
defer this.CreateLogInfo(codes.HTTPCacheTask_LogDeleteHTTPCacheTask, params.TaskId)
_, err := this.RPC().HTTPCacheTaskRPC().DeleteHTTPCacheTask(this.AdminContext(), &pb.DeleteHTTPCacheTaskRequest{
HttpCacheTaskId: params.TaskId,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,98 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
"strings"
)
type FetchAction struct {
actionutils.ParentAction
}
func (this *FetchAction) Init() {
this.Nav("", "", "fetch")
}
func (this *FetchAction) RunGet(params struct{}) {
// 初始化菜单数据
err := InitMenu(this.Parent())
if err != nil {
this.ErrorPage(err)
return
}
this.Show()
}
func (this *FetchAction) RunPost(params struct {
Keys string
Must *actions.Must
CSRF *actionutils.CSRF
}) {
defer this.CreateLogInfo(codes.HTTPCacheTask_LogCreateHTTPCacheTaskFetch)
if len(params.Keys) == 0 {
this.Fail("请输入要预热的Key列表")
}
// 检查Key
var realKeys = []string{}
for _, key := range strings.Split(params.Keys, "\n") {
key = strings.TrimSpace(key)
if len(key) == 0 {
continue
}
if lists.ContainsString(realKeys, key) {
continue
}
realKeys = append(realKeys, key)
}
if len(realKeys) == 0 {
this.Fail("请输入要预热的Key列表")
}
// 校验Key
validateResp, err := this.RPC().HTTPCacheTaskKeyRPC().ValidateHTTPCacheTaskKeys(this.AdminContext(), &pb.ValidateHTTPCacheTaskKeysRequest{Keys: realKeys})
if err != nil {
this.ErrorPage(err)
return
}
var failKeyMaps = []maps.Map{}
if len(validateResp.FailKeys) > 0 {
for _, key := range validateResp.FailKeys {
failKeyMaps = append(failKeyMaps, maps.Map{
"key": key.Key,
"reason": cacheutils.KeyFailReason(key.ReasonCode),
})
}
}
this.Data["failKeys"] = failKeyMaps
if len(failKeyMaps) > 0 {
this.Fail("有" + types.String(len(failKeyMaps)) + "个Key无法完成操作请删除后重试")
}
// 提交任务
_, err = this.RPC().HTTPCacheTaskRPC().CreateHTTPCacheTask(this.AdminContext(), &pb.CreateHTTPCacheTaskRequest{
Type: "fetch",
KeyType: "key",
Keys: realKeys,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,103 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
"strings"
)
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.Nav("", "", "purge")
}
func (this *IndexAction) RunGet(params struct {
KeyType string
}) {
// 初始化菜单数据
err := InitMenu(this.Parent())
if err != nil {
this.ErrorPage(err)
return
}
this.Data["keyType"] = params.KeyType
this.Show()
}
func (this *IndexAction) RunPost(params struct {
KeyType string
Keys string
Must *actions.Must
CSRF *actionutils.CSRF
}) {
defer this.CreateLogInfo(codes.HTTPCacheTask_LogCreateHTTPCacheTaskPurge)
if len(params.Keys) == 0 {
this.Fail("请输入要刷新的Key列表")
}
// 检查Key
var realKeys = []string{}
for _, key := range strings.Split(params.Keys, "\n") {
key = strings.TrimSpace(key)
if len(key) == 0 {
continue
}
if lists.ContainsString(realKeys, key) {
continue
}
realKeys = append(realKeys, key)
}
if len(realKeys) == 0 {
this.Fail("请输入要刷新的Key列表")
}
// 校验Key
validateResp, err := this.RPC().HTTPCacheTaskKeyRPC().ValidateHTTPCacheTaskKeys(this.AdminContext(), &pb.ValidateHTTPCacheTaskKeysRequest{Keys: realKeys})
if err != nil {
this.ErrorPage(err)
return
}
var failKeyMaps = []maps.Map{}
if len(validateResp.FailKeys) > 0 {
for _, key := range validateResp.FailKeys {
failKeyMaps = append(failKeyMaps, maps.Map{
"key": key.Key,
"reason": cacheutils.KeyFailReason(key.ReasonCode),
})
}
}
this.Data["failKeys"] = failKeyMaps
if len(failKeyMaps) > 0 {
this.Fail("有" + types.String(len(failKeyMaps)) + "个Key无法完成操作请删除后重试")
}
// 提交任务
_, err = this.RPC().HTTPCacheTaskRPC().CreateHTTPCacheTask(this.AdminContext(), &pb.CreateHTTPCacheTaskRequest{
Type: "purge",
KeyType: params.KeyType,
Keys: realKeys,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,24 @@
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
"github.com/iwind/TeaGo"
)
func init() {
TeaGo.BeforeStart(func(server *TeaGo.Server) {
server.
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
Data("teaMenu", "servers").
Data("teaSubMenu", "cacheBatch").
Prefix("/servers/components/cache/batch").
GetPost("", new(IndexAction)).
GetPost("/fetch", new(FetchAction)).
Get("/tasks", new(TasksAction)).
GetPost("/task", new(TaskAction)).
Post("/deleteTask", new(DeleteTaskAction)).
Post("/resetTask", new(ResetTaskAction)).
EndAll()
})
}

View File

@@ -0,0 +1,27 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
type ResetTaskAction struct {
actionutils.ParentAction
}
func (this *ResetTaskAction) RunPost(params struct {
TaskId int64
}) {
this.CreateLogInfo(codes.HTTPCacheTask_LogResetHTTPCacheTask, params.TaskId)
_, err := this.RPC().HTTPCacheTaskRPC().ResetHTTPCacheTask(this.AdminContext(), &pb.ResetHTTPCacheTaskRequest{HttpCacheTaskId: params.TaskId})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,137 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package cache
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time"
"sort"
)
type TaskAction struct {
actionutils.ParentAction
}
func (this *TaskAction) Init() {
this.Nav("", "", "task")
}
func (this *TaskAction) RunGet(params struct {
TaskId int64
}) {
// 初始化菜单数据
err := InitMenu(this.Parent())
if err != nil {
this.ErrorPage(err)
return
}
if !this.readTask(params.TaskId) {
return
}
this.Show()
}
func (this *TaskAction) RunPost(params struct {
TaskId int64
}) {
if !this.readTask(params.TaskId) {
return
}
this.Success()
}
// 读取任务信息
func (this *TaskAction) readTask(taskId int64) (ok bool) {
taskResp, err := this.RPC().HTTPCacheTaskRPC().FindEnabledHTTPCacheTask(this.AdminContext(), &pb.FindEnabledHTTPCacheTaskRequest{HttpCacheTaskId: taskId})
if err != nil {
this.ErrorPage(err)
return
}
var task = taskResp.HttpCacheTask
if task == nil {
this.NotFound("HTTPCacheTask", taskId)
return
}
// 用户
var userMap = maps.Map{"id": 0, "username": "", "fullname": ""}
if task.User != nil {
userMap = maps.Map{
"id": task.User.Id,
"username": task.User.Username,
"fullname": task.User.Fullname,
}
}
// keys
var keyMaps = []maps.Map{}
for _, key := range task.HttpCacheTaskKeys {
// 错误信息
var errorMaps = []maps.Map{}
if len(key.ErrorsJSON) > 0 {
var m = map[int64]string{}
err = json.Unmarshal(key.ErrorsJSON, &m)
if err != nil {
this.ErrorPage(err)
return
}
for nodeId, errString := range m {
errorMaps = append(errorMaps, maps.Map{
"nodeId": nodeId,
"error": errString,
})
}
}
// 错误信息排序
if len(errorMaps) > 0 {
sort.Slice(errorMaps, func(i, j int) bool {
var m1 = errorMaps[i]
var m2 = errorMaps[j]
return m1.GetInt64("nodeId") < m2.GetInt64("nodeId")
})
}
// 集群信息
var clusterMap = maps.Map{
"id": 0,
"name": "",
}
if key.NodeCluster != nil {
clusterMap = maps.Map{
"id": key.NodeCluster.Id,
"name": key.NodeCluster.Name,
}
}
keyMaps = append(keyMaps, maps.Map{
"key": key.Key,
"isDone": key.IsDone,
"isDoing": key.IsDoing,
"errors": errorMaps,
"cluster": clusterMap,
})
}
this.Data["task"] = maps.Map{
"id": task.Id,
"type": task.Type,
"keyType": task.KeyType,
"createdTime": timeutil.FormatTime("Y-m-d H:i:s", task.CreatedAt),
"doneTime": timeutil.FormatTime("Y-m-d H:i:s", task.DoneAt),
"isDone": task.IsDone,
"isOk": task.IsOk,
"keys": keyMaps,
"user": userMap,
}
ok = true
return
}

View File

@@ -0,0 +1,73 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/maps"
timeutil "github.com/iwind/TeaGo/utils/time"
)
type TasksAction struct {
actionutils.ParentAction
}
func (this *TasksAction) Init() {
this.Nav("", "", "task")
}
func (this *TasksAction) RunGet(params struct{}) {
// 初始化菜单数据
err := InitMenu(this.Parent())
if err != nil {
this.ErrorPage(err)
return
}
// 任务数量
countResp, err := this.RPC().HTTPCacheTaskRPC().CountHTTPCacheTasks(this.AdminContext(), &pb.CountHTTPCacheTasksRequest{})
if err != nil {
this.ErrorPage(err)
return
}
var count = countResp.Count
var page = this.NewPage(count)
this.Data["page"] = page.AsHTML()
// 任务列表
var taskMaps = []maps.Map{}
tasksResp, err := this.RPC().HTTPCacheTaskRPC().ListHTTPCacheTasks(this.AdminContext(), &pb.ListHTTPCacheTasksRequest{
Offset: page.Offset,
Size: page.Size,
})
if err != nil {
this.ErrorPage(err)
return
}
for _, task := range tasksResp.HttpCacheTasks {
var userMap = maps.Map{"id": 0, "username": "", "fullname": ""}
if task.User != nil {
userMap = maps.Map{
"id": task.User.Id,
"username": task.User.Username,
"fullname": task.User.Fullname,
}
}
taskMaps = append(taskMaps, maps.Map{
"id": task.Id,
"type": task.Type,
"keyType": task.KeyType,
"isDone": task.IsDone,
"isOk": task.IsOk,
"createdTime": timeutil.FormatTime("Y-m-d H:i:s", task.CreatedAt),
"description": task.Description,
"user": userMap,
})
}
this.Data["tasks"] = taskMaps
this.Show()
}

View File

@@ -0,0 +1,24 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/rpc"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
func InitMenu(parent *actionutils.ParentAction) error {
rpcClient, err := rpc.SharedRPC()
if err != nil {
return err
}
countTasksResp, err := rpcClient.HTTPCacheTaskRPC().CountDoingHTTPCacheTasks(parent.AdminContext(), &pb.CountDoingHTTPCacheTasksRequest{})
if err != nil {
return err
}
parent.Data["countDoingTasks"] = countTasksResp.Count
return nil
}

View File

@@ -0,0 +1,56 @@
package cacheutils
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/errors"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
)
// FindCachePolicyNameWithoutError 查找缓存策略名称并忽略错误
func FindCachePolicyNameWithoutError(parent *actionutils.ParentAction, cachePolicyId int64) string {
policy, err := FindCachePolicy(parent, cachePolicyId)
if err != nil {
return ""
}
if policy == nil {
return ""
}
return policy.Name
}
// FindCachePolicy 查找缓存策略配置
func FindCachePolicy(parent *actionutils.ParentAction, cachePolicyId int64) (*serverconfigs.HTTPCachePolicy, error) {
resp, err := parent.RPC().HTTPCachePolicyRPC().FindEnabledHTTPCachePolicyConfig(parent.AdminContext(), &pb.FindEnabledHTTPCachePolicyConfigRequest{HttpCachePolicyId: cachePolicyId})
if err != nil {
return nil, err
}
if len(resp.HttpCachePolicyJSON) == 0 {
return nil, errors.New("cache policy not found")
}
var config = &serverconfigs.HTTPCachePolicy{}
err = json.Unmarshal(resp.HttpCachePolicyJSON, config)
if err != nil {
return nil, err
}
return config, nil
}
// KeyFailReason Key相关失败原因
func KeyFailReason(reasonCode string) string {
switch reasonCode {
case "requireKey":
return "空的Key"
case "requireDomain":
return "找不到Key对应的域名"
case "requireServer":
return "找不到Key对应的网站"
case "requireUser":
return "该域名不属于当前用户"
case "requireClusterId":
return "该网站没有部署到集群"
}
return "未知错误"
}

View File

@@ -0,0 +1,98 @@
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/nodeutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/messageconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
"net/http"
"strconv"
)
type CleanAction struct {
actionutils.ParentAction
}
func (this *CleanAction) Init() {
this.Nav("", "", "clean")
}
func (this *CleanAction) RunGet(params struct {
CachePolicyId int64
}) {
// 默认的集群ID
cookie, err := this.Request.Cookie("cache_cluster_id")
if cookie != nil && err == nil {
this.Data["clusterId"] = types.Int64(cookie.Value)
}
// 集群列表
clustersResp, err := this.RPC().NodeClusterRPC().FindAllEnabledNodeClustersWithHTTPCachePolicyId(this.AdminContext(), &pb.FindAllEnabledNodeClustersWithHTTPCachePolicyIdRequest{HttpCachePolicyId: params.CachePolicyId})
if err != nil {
this.ErrorPage(err)
return
}
clusterMaps := []maps.Map{}
for _, cluster := range clustersResp.NodeClusters {
clusterMaps = append(clusterMaps, maps.Map{
"id": cluster.Id,
"name": cluster.Name,
})
}
this.Data["clusters"] = clusterMaps
this.Show()
}
func (this *CleanAction) RunPost(params struct {
CachePolicyId int64
ClusterId int64
Must *actions.Must
}) {
// 记录clusterId
this.AddCookie(&http.Cookie{
Name: "cache_cluster_id",
Value: strconv.FormatInt(params.ClusterId, 10),
})
cachePolicyResp, err := this.RPC().HTTPCachePolicyRPC().FindEnabledHTTPCachePolicyConfig(this.AdminContext(), &pb.FindEnabledHTTPCachePolicyConfigRequest{HttpCachePolicyId: params.CachePolicyId})
if err != nil {
this.ErrorPage(err)
return
}
cachePolicyJSON := cachePolicyResp.HttpCachePolicyJSON
if len(cachePolicyJSON) == 0 {
this.Fail("找不到要操作的缓存策略")
}
// 发送命令
msg := &messageconfigs.CleanCacheMessage{
CachePolicyJSON: cachePolicyJSON,
}
results, err := nodeutils.SendMessageToCluster(this.AdminContext(), params.ClusterId, messageconfigs.MessageCodeCleanCache, msg, 60, false)
if err != nil {
this.ErrorPage(err)
return
}
isAllOk := true
for _, result := range results {
if !result.IsOK {
isAllOk = false
break
}
}
this.Data["isAllOk"] = isAllOk
this.Data["results"] = results
// 创建日志
defer this.CreateLogInfo(codes.ServerCachePolicy_LogCleanAll, params.CachePolicyId)
this.Success()
}

View File

@@ -0,0 +1,22 @@
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
// 计算可用缓存策略数量
type CountAction struct {
actionutils.ParentAction
}
func (this *CountAction) RunPost(params struct{}) {
countResp, err := this.RPC().HTTPCachePolicyRPC().CountAllEnabledHTTPCachePolicies(this.AdminContext(), &pb.CountAllEnabledHTTPCachePoliciesRequest{})
if err != nil {
this.ErrorPage(err)
return
}
this.Data["count"] = countResp.Count
this.Success()
}

View File

@@ -0,0 +1,142 @@
package cache
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps"
)
type CreatePopupAction struct {
actionutils.ParentAction
}
func (this *CreatePopupAction) Init() {
this.Nav("", "", "")
}
func (this *CreatePopupAction) RunGet(params struct{}) {
this.Data["types"] = serverconfigs.AllCachePolicyStorageTypes
this.Show()
}
func (this *CreatePopupAction) RunPost(params struct {
Name string
Type string
// file
FileDir string
FileMemoryCapacityJSON []byte
FileOpenFileCacheMax int
FileEnableSendfile bool
FileMinFreeSizeJSON []byte
CapacityJSON []byte
MaxSizeJSON []byte
FetchTimeoutJSON []byte
SyncCompressionCache bool
EnableMMAP bool
EnableIncompletePartialContent bool
Description string
IsOn bool
Must *actions.Must
}) {
params.Must.
Field("name", params.Name).
Require("请输入策略名称")
// 校验选项
var options any
switch params.Type {
case serverconfigs.CachePolicyStorageFile:
params.Must.
Field("fileDir", params.FileDir).
Require("请输入缓存目录")
var memoryCapacity = &shared.SizeCapacity{}
if len(params.FileMemoryCapacityJSON) > 0 {
err := json.Unmarshal(params.FileMemoryCapacityJSON, memoryCapacity)
if err != nil {
this.ErrorPage(err)
return
}
}
var openFileCacheConfig *serverconfigs.OpenFileCacheConfig
if params.FileOpenFileCacheMax > 0 {
openFileCacheConfig = &serverconfigs.OpenFileCacheConfig{
IsOn: true,
Max: params.FileOpenFileCacheMax,
}
}
var minFreeSize = &shared.SizeCapacity{}
var minFreeSizeJSON = params.FileMinFreeSizeJSON
if !utils.JSONIsNull(minFreeSizeJSON) {
_, err := utils.JSONDecodeConfig(minFreeSizeJSON, minFreeSize)
if err != nil {
this.ErrorPage(err)
return
}
if minFreeSize.Count < 0 {
minFreeSize.Count = 0
}
}
options = &serverconfigs.HTTPFileCacheStorage{
Dir: params.FileDir,
MemoryPolicy: &serverconfigs.HTTPCachePolicy{
Capacity: memoryCapacity,
},
OpenFileCache: openFileCacheConfig,
EnableSendfile: params.FileEnableSendfile,
MinFreeSize: minFreeSize,
EnableMMAP: params.EnableMMAP,
EnableIncompletePartialContent: params.EnableIncompletePartialContent,
}
case serverconfigs.CachePolicyStorageMemory:
options = &serverconfigs.HTTPMemoryCacheStorage{}
default:
this.Fail("请选择正确的缓存类型")
}
optionsJSON, err := json.Marshal(options)
if err != nil {
this.ErrorPage(err)
return
}
createResp, err := this.RPC().HTTPCachePolicyRPC().CreateHTTPCachePolicy(this.AdminContext(), &pb.CreateHTTPCachePolicyRequest{
IsOn: params.IsOn,
Name: params.Name,
Description: params.Description,
CapacityJSON: params.CapacityJSON,
MaxSizeJSON: params.MaxSizeJSON,
FetchTimeoutJSON: params.FetchTimeoutJSON,
Type: params.Type,
OptionsJSON: optionsJSON,
SyncCompressionCache: params.SyncCompressionCache,
})
if err != nil {
this.ErrorPage(err)
return
}
// 返回数据
this.Data["cachePolicy"] = maps.Map{
"id": createResp.HttpCachePolicyId,
"name": params.Name,
}
// 创建日志
defer this.CreateLogInfo(codes.ServerCachePolicy_LogCreateCachePolicy, createResp.HttpCachePolicyId)
this.Success()
}

View File

@@ -0,0 +1,36 @@
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
type DeleteAction struct {
actionutils.ParentAction
}
func (this *DeleteAction) RunPost(params struct {
CachePolicyId int64
}) {
// 检查是否被引用
countResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClustersWithHTTPCachePolicyId(this.AdminContext(), &pb.CountAllEnabledNodeClustersWithHTTPCachePolicyIdRequest{HttpCachePolicyId: params.CachePolicyId})
if err != nil {
this.ErrorPage(err)
return
}
if countResp.Count > 0 {
this.Fail("此缓存策略正在被有些集群引用,请修改后再删除。")
}
_, err = this.RPC().HTTPCachePolicyRPC().DeleteHTTPCachePolicy(this.AdminContext(), &pb.DeleteHTTPCachePolicyRequest{HttpCachePolicyId: params.CachePolicyId})
if err != nil {
this.ErrorPage(err)
return
}
// 创建日志
defer this.CreateLogInfo(codes.ServerCachePolicy_LogDeleteCachePolicy, params.CachePolicyId)
this.Success()
}

View File

@@ -0,0 +1,128 @@
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
"net/http"
"strconv"
"strings"
)
type FetchAction struct {
actionutils.ParentAction
}
func (this *FetchAction) Init() {
this.Nav("", "", "fetch")
}
func (this *FetchAction) RunGet(params struct {
CachePolicyId int64
}) {
// 默认的集群ID
cookie, err := this.Request.Cookie("cache_cluster_id")
if cookie != nil && err == nil {
this.Data["clusterId"] = types.Int64(cookie.Value)
}
// 集群列表
clustersResp, err := this.RPC().NodeClusterRPC().FindAllEnabledNodeClustersWithHTTPCachePolicyId(this.AdminContext(), &pb.FindAllEnabledNodeClustersWithHTTPCachePolicyIdRequest{HttpCachePolicyId: params.CachePolicyId})
if err != nil {
this.ErrorPage(err)
return
}
clusterMaps := []maps.Map{}
for _, cluster := range clustersResp.NodeClusters {
clusterMaps = append(clusterMaps, maps.Map{
"id": cluster.Id,
"name": cluster.Name,
})
}
this.Data["clusters"] = clusterMaps
this.Show()
}
func (this *FetchAction) RunPost(params struct {
CachePolicyId int64
ClusterId int64
Keys string
Must *actions.Must
}) {
// 创建日志
defer this.CreateLogInfo(codes.ServerCachePolicy_LogFetchCaches, params.CachePolicyId)
// 记录clusterId
this.AddCookie(&http.Cookie{
Name: "cache_cluster_id",
Value: strconv.FormatInt(params.ClusterId, 10),
})
cachePolicyResp, err := this.RPC().HTTPCachePolicyRPC().FindEnabledHTTPCachePolicyConfig(this.AdminContext(), &pb.FindEnabledHTTPCachePolicyConfigRequest{HttpCachePolicyId: params.CachePolicyId})
if err != nil {
this.ErrorPage(err)
return
}
cachePolicyJSON := cachePolicyResp.HttpCachePolicyJSON
if len(cachePolicyJSON) == 0 {
this.Fail("找不到要操作的缓存策略")
}
if len(params.Keys) == 0 {
this.Fail("请输入要预热的Key列表")
}
realKeys := []string{}
for _, key := range strings.Split(params.Keys, "\n") {
key = strings.TrimSpace(key)
if len(key) == 0 {
continue
}
if lists.ContainsString(realKeys, key) {
continue
}
realKeys = append(realKeys, key)
}
// 校验Key
// 这里暂时不校验服务ID
validateResp, err := this.RPC().HTTPCacheTaskKeyRPC().ValidateHTTPCacheTaskKeys(this.AdminContext(), &pb.ValidateHTTPCacheTaskKeysRequest{Keys: realKeys})
if err != nil {
this.ErrorPage(err)
return
}
var failKeyMaps = []maps.Map{}
if len(validateResp.FailKeys) > 0 {
for _, key := range validateResp.FailKeys {
failKeyMaps = append(failKeyMaps, maps.Map{
"key": key.Key,
"reason": cacheutils.KeyFailReason(key.ReasonCode),
})
}
}
this.Data["failKeys"] = failKeyMaps
if len(failKeyMaps) > 0 {
this.Fail("有" + types.String(len(failKeyMaps)) + "个Key无法完成操作请删除后重试")
}
// 提交任务
_, err = this.RPC().HTTPCacheTaskRPC().CreateHTTPCacheTask(this.AdminContext(), &pb.CreateHTTPCacheTaskRequest{
Type: "fetch",
KeyType: "key",
Keys: realKeys,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,36 @@
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils"
"github.com/iwind/TeaGo/actions"
"net/http"
)
type Helper struct {
}
func NewHelper() *Helper {
return &Helper{}
}
func (this *Helper) BeforeAction(actionPtr actions.ActionWrapper) {
action := actionPtr.Object()
if action.Request.Method != http.MethodGet {
return
}
action.Data["mainTab"] = "component"
action.Data["secondMenuItem"] = "cache"
cachePolicyId := action.ParamInt64("cachePolicyId")
action.Data["cachePolicyId"] = cachePolicyId
parentActionObj, ok := actionPtr.(interface {
Parent() *actionutils.ParentAction
})
if ok {
var parentAction = parentActionObj.Parent()
action.Data["cachePolicyName"] = cacheutils.FindCachePolicyNameWithoutError(parentAction, cachePolicyId)
}
}

View File

@@ -0,0 +1,81 @@
package cache
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/iwind/TeaGo/maps"
)
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.FirstMenu("index")
}
func (this *IndexAction) RunGet(params struct {
ClusterId int64
Keyword string
StorageType string
}) {
this.Data["keyword"] = params.Keyword
this.Data["clusterId"] = params.ClusterId
this.Data["storageType"] = params.StorageType
countResp, err := this.RPC().HTTPCachePolicyRPC().CountAllEnabledHTTPCachePolicies(this.AdminContext(), &pb.CountAllEnabledHTTPCachePoliciesRequest{
NodeClusterId: params.ClusterId,
Keyword: params.Keyword,
Type: params.StorageType,
})
if err != nil {
this.ErrorPage(err)
return
}
count := countResp.Count
page := this.NewPage(count)
this.Data["page"] = page.AsHTML()
listResp, err := this.RPC().HTTPCachePolicyRPC().ListEnabledHTTPCachePolicies(this.AdminContext(), &pb.ListEnabledHTTPCachePoliciesRequest{
Keyword: params.Keyword,
NodeClusterId: params.ClusterId,
Type: params.StorageType,
Offset: page.Offset,
Size: page.Size,
})
if err != nil {
this.ErrorPage(err)
return
}
cachePoliciesJSON := listResp.HttpCachePoliciesJSON
cachePolicies := []*serverconfigs.HTTPCachePolicy{}
err = json.Unmarshal(cachePoliciesJSON, &cachePolicies)
if err != nil {
this.ErrorPage(err)
return
}
this.Data["cachePolicies"] = cachePolicies
infos := []maps.Map{}
for _, cachePolicy := range cachePolicies {
countClustersResp, err := this.RPC().NodeClusterRPC().CountAllEnabledNodeClustersWithHTTPCachePolicyId(this.AdminContext(), &pb.CountAllEnabledNodeClustersWithHTTPCachePolicyIdRequest{HttpCachePolicyId: cachePolicy.Id})
if err != nil {
this.ErrorPage(err)
return
}
countClusters := countClustersResp.Count
infos = append(infos, maps.Map{
"typeName": serverconfigs.FindCachePolicyStorageName(cachePolicy.Type),
"countClusters": countClusters,
})
}
this.Data["infos"] = infos
// 所有的存储类型
this.Data["storageTypes"] = serverconfigs.AllCachePolicyStorageTypes
this.Show()
}

View File

@@ -0,0 +1,34 @@
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
"github.com/iwind/TeaGo"
)
func init() {
TeaGo.BeforeStart(func(server *TeaGo.Server) {
server.
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeServer)).
Helper(NewHelper()).
Data("teaMenu", "servers").
Data("teaSubMenu", "cache").
Prefix("/servers/components/cache").
Get("", new(IndexAction)).
GetPost("/createPopup", new(CreatePopupAction)).
Get("/policy", new(PolicyAction)).
GetPost("/update", new(UpdateAction)).
GetPost("/clean", new(CleanAction)).
GetPost("/fetch", new(FetchAction)).
GetPost("/purge", new(PurgeAction)).
GetPost("/stat", new(StatAction)).
GetPost("/test", new(TestAction)).
Post("/delete", new(DeleteAction)).
Post("/testRead", new(TestReadAction)).
Post("/testWrite", new(TestWriteAction)).
Get("/selectPopup", new(SelectPopupAction)).
Post("/count", new(CountAction)).
Post("/updateRefs", new(UpdateRefsAction)).
EndAll()
})
}

View File

@@ -0,0 +1,53 @@
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/iwind/TeaGo/maps"
)
type PolicyAction struct {
actionutils.ParentAction
}
func (this *PolicyAction) Init() {
this.Nav("", "", "index")
}
func (this *PolicyAction) RunGet(params struct {
CachePolicyId int64
}) {
cachePolicy, err := cacheutils.FindCachePolicy(this.Parent(), params.CachePolicyId)
if err != nil {
this.ErrorPage(err)
return
}
this.Data["cachePolicy"] = cachePolicy
// 预热超时时间
this.Data["fetchTimeoutString"] = ""
if cachePolicy.FetchTimeout != nil && cachePolicy.FetchTimeout.Count > 0 {
this.Data["fetchTimeoutString"] = cachePolicy.FetchTimeout.Description()
}
this.Data["typeName"] = serverconfigs.FindCachePolicyStorageName(cachePolicy.Type)
// 正在使用此策略的集群
clustersResp, err := this.RPC().NodeClusterRPC().FindAllEnabledNodeClustersWithHTTPCachePolicyId(this.AdminContext(), &pb.FindAllEnabledNodeClustersWithHTTPCachePolicyIdRequest{HttpCachePolicyId: params.CachePolicyId})
if err != nil {
this.ErrorPage(err)
return
}
var clusterMaps = []maps.Map{}
for _, cluster := range clustersResp.NodeClusters {
clusterMaps = append(clusterMaps, maps.Map{
"id": cluster.Id,
"name": cluster.Name,
})
}
this.Data["clusters"] = clusterMaps
this.Show()
}

View File

@@ -0,0 +1,126 @@
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/servers/components/cache/cacheutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
"net/http"
"strconv"
"strings"
)
type PurgeAction struct {
actionutils.ParentAction
}
func (this *PurgeAction) Init() {
this.Nav("", "", "purge")
}
func (this *PurgeAction) RunGet(params struct {
CachePolicyId int64
}) {
// 默认的集群ID
cookie, err := this.Request.Cookie("cache_cluster_id")
if cookie != nil && err == nil {
this.Data["clusterId"] = types.Int64(cookie.Value)
}
// 集群列表
clustersResp, err := this.RPC().NodeClusterRPC().FindAllEnabledNodeClustersWithHTTPCachePolicyId(this.AdminContext(), &pb.FindAllEnabledNodeClustersWithHTTPCachePolicyIdRequest{HttpCachePolicyId: params.CachePolicyId})
if err != nil {
this.ErrorPage(err)
return
}
clusterMaps := []maps.Map{}
for _, cluster := range clustersResp.NodeClusters {
clusterMaps = append(clusterMaps, maps.Map{
"id": cluster.Id,
"name": cluster.Name,
})
}
this.Data["clusters"] = clusterMaps
this.Show()
}
func (this *PurgeAction) RunPost(params struct {
CachePolicyId int64
ClusterId int64
KeyType string
Keys string
Must *actions.Must
}) {
// 创建日志
defer this.CreateLogInfo(codes.ServerCachePolicy_LogPurgeCaches, params.CachePolicyId)
// 记录clusterId
this.AddCookie(&http.Cookie{
Name: "cache_cluster_id",
Value: strconv.FormatInt(params.ClusterId, 10),
})
cachePolicyResp, err := this.RPC().HTTPCachePolicyRPC().FindEnabledHTTPCachePolicyConfig(this.AdminContext(), &pb.FindEnabledHTTPCachePolicyConfigRequest{HttpCachePolicyId: params.CachePolicyId})
if err != nil {
this.ErrorPage(err)
return
}
cachePolicyJSON := cachePolicyResp.HttpCachePolicyJSON
if len(cachePolicyJSON) == 0 {
this.Fail("找不到要操作的缓存策略")
}
if len(params.Keys) == 0 {
this.Fail("请输入要删除的Key列表")
}
realKeys := []string{}
for _, key := range strings.Split(params.Keys, "\n") {
key = strings.TrimSpace(key)
if len(key) == 0 {
continue
}
if lists.ContainsString(realKeys, key) {
continue
}
realKeys = append(realKeys, key)
}
// 校验Key
validateResp, err := this.RPC().HTTPCacheTaskKeyRPC().ValidateHTTPCacheTaskKeys(this.AdminContext(), &pb.ValidateHTTPCacheTaskKeysRequest{Keys: realKeys})
if err != nil {
this.ErrorPage(err)
return
}
var failKeyMaps = []maps.Map{}
if len(validateResp.FailKeys) > 0 {
for _, key := range validateResp.FailKeys {
failKeyMaps = append(failKeyMaps, maps.Map{
"key": key.Key,
"reason": cacheutils.KeyFailReason(key.ReasonCode),
})
}
}
this.Data["failKeys"] = failKeyMaps
if len(failKeyMaps) > 0 {
this.Fail("有" + types.String(len(failKeyMaps)) + "个Key无法完成操作请删除后重试")
}
// 提交任务
_, err = this.RPC().HTTPCacheTaskRPC().CreateHTTPCacheTask(this.AdminContext(), &pb.CreateHTTPCacheTaskRequest{
Type: "purge",
KeyType: params.KeyType,
Keys: realKeys,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,60 @@
package cache
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/iwind/TeaGo/maps"
)
type SelectPopupAction struct {
actionutils.ParentAction
}
func (this *SelectPopupAction) Init() {
this.Nav("", "", "")
}
func (this *SelectPopupAction) RunGet(params struct{}) {
countResp, err := this.RPC().HTTPCachePolicyRPC().CountAllEnabledHTTPCachePolicies(this.AdminContext(), &pb.CountAllEnabledHTTPCachePoliciesRequest{})
if err != nil {
this.ErrorPage(err)
return
}
count := countResp.Count
page := this.NewPage(count)
this.Data["page"] = page.AsHTML()
cachePoliciesResp, err := this.RPC().HTTPCachePolicyRPC().ListEnabledHTTPCachePolicies(this.AdminContext(), &pb.ListEnabledHTTPCachePoliciesRequest{
Offset: page.Offset,
Size: page.Size,
})
if err != nil {
this.ErrorPage(err)
return
}
cachePolicies := []*serverconfigs.HTTPCachePolicy{}
if len(cachePoliciesResp.HttpCachePoliciesJSON) > 0 {
err = json.Unmarshal(cachePoliciesResp.HttpCachePoliciesJSON, &cachePolicies)
if err != nil {
this.ErrorPage(err)
return
}
}
policyMaps := []maps.Map{}
for _, cachePolicy := range cachePolicies {
policyMaps = append(policyMaps, maps.Map{
"id": cachePolicy.Id,
"name": cachePolicy.Name,
"description": cachePolicy.Description,
"isOn": cachePolicy.IsOn,
})
}
this.Data["cachePolicies"] = policyMaps
this.Show()
}

View File

@@ -0,0 +1,98 @@
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/nodeutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/messageconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
"net/http"
"strconv"
)
type StatAction struct {
actionutils.ParentAction
}
func (this *StatAction) Init() {
this.Nav("", "", "stat")
}
func (this *StatAction) RunGet(params struct {
CachePolicyId int64
}) {
// 默认的集群ID
cookie, err := this.Request.Cookie("cache_cluster_id")
if cookie != nil && err == nil {
this.Data["clusterId"] = types.Int64(cookie.Value)
}
// 集群列表
clustersResp, err := this.RPC().NodeClusterRPC().FindAllEnabledNodeClustersWithHTTPCachePolicyId(this.AdminContext(), &pb.FindAllEnabledNodeClustersWithHTTPCachePolicyIdRequest{HttpCachePolicyId: params.CachePolicyId})
if err != nil {
this.ErrorPage(err)
return
}
clusterMaps := []maps.Map{}
for _, cluster := range clustersResp.NodeClusters {
clusterMaps = append(clusterMaps, maps.Map{
"id": cluster.Id,
"name": cluster.Name,
})
}
this.Data["clusters"] = clusterMaps
this.Show()
}
func (this *StatAction) RunPost(params struct {
CachePolicyId int64
ClusterId int64
Must *actions.Must
}) {
// 记录clusterId
this.AddCookie(&http.Cookie{
Name: "cache_cluster_id",
Value: strconv.FormatInt(params.ClusterId, 10),
})
cachePolicyResp, err := this.RPC().HTTPCachePolicyRPC().FindEnabledHTTPCachePolicyConfig(this.AdminContext(), &pb.FindEnabledHTTPCachePolicyConfigRequest{HttpCachePolicyId: params.CachePolicyId})
if err != nil {
this.ErrorPage(err)
return
}
cachePolicyJSON := cachePolicyResp.HttpCachePolicyJSON
if len(cachePolicyJSON) == 0 {
this.Fail("找不到要操作的缓存策略")
}
// 发送命令
msg := &messageconfigs.StatCacheMessage{
CachePolicyJSON: cachePolicyJSON,
}
results, err := nodeutils.SendMessageToCluster(this.AdminContext(), params.ClusterId, messageconfigs.MessageCodeStatCache, msg, 10, false)
if err != nil {
this.ErrorPage(err)
return
}
isAllOk := true
for _, result := range results {
if !result.IsOK {
isAllOk = false
break
}
}
this.Data["isAllOk"] = isAllOk
this.Data["results"] = results
// 创建日志
defer this.CreateLogInfo(codes.ServerCachePolicy_LogStatCaches, params.CachePolicyId)
this.Success()
}

View File

@@ -0,0 +1,43 @@
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/maps"
"github.com/iwind/TeaGo/types"
)
type TestAction struct {
actionutils.ParentAction
}
func (this *TestAction) Init() {
this.Nav("", "", "test")
}
func (this *TestAction) RunGet(params struct {
CachePolicyId int64
}) {
// 默认的集群ID
cookie, err := this.Request.Cookie("cache_cluster_id")
if cookie != nil && err == nil {
this.Data["clusterId"] = types.Int64(cookie.Value)
}
// 集群列表
clustersResp, err := this.RPC().NodeClusterRPC().FindAllEnabledNodeClustersWithHTTPCachePolicyId(this.AdminContext(), &pb.FindAllEnabledNodeClustersWithHTTPCachePolicyIdRequest{HttpCachePolicyId: params.CachePolicyId})
if err != nil {
this.ErrorPage(err)
return
}
clusterMaps := []maps.Map{}
for _, cluster := range clustersResp.NodeClusters {
clusterMaps = append(clusterMaps, maps.Map{
"id": cluster.Id,
"name": cluster.Name,
})
}
this.Data["clusters"] = clusterMaps
this.Show()
}

View File

@@ -0,0 +1,64 @@
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/nodeutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/messageconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"net/http"
"strconv"
)
type TestReadAction struct {
actionutils.ParentAction
}
func (this *TestReadAction) RunPost(params struct {
ClusterId int64
CachePolicyId int64
Key string
}) {
// 记录clusterId
this.AddCookie(&http.Cookie{
Name: "cache_cluster_id",
Value: strconv.FormatInt(params.ClusterId, 10),
})
cachePolicyResp, err := this.RPC().HTTPCachePolicyRPC().FindEnabledHTTPCachePolicyConfig(this.AdminContext(), &pb.FindEnabledHTTPCachePolicyConfigRequest{HttpCachePolicyId: params.CachePolicyId})
if err != nil {
this.ErrorPage(err)
return
}
cachePolicyJSON := cachePolicyResp.HttpCachePolicyJSON
if len(cachePolicyJSON) == 0 {
this.Fail("找不到要操作的缓存策略")
}
// 发送命令
msg := &messageconfigs.ReadCacheMessage{
CachePolicyJSON: cachePolicyJSON,
Key: params.Key,
}
results, err := nodeutils.SendMessageToCluster(this.AdminContext(), params.ClusterId, messageconfigs.MessageCodeReadCache, msg, 10, false)
if err != nil {
this.ErrorPage(err)
return
}
isAllOk := true
for _, result := range results {
if !result.IsOK {
isAllOk = false
break
}
}
this.Data["isAllOk"] = isAllOk
this.Data["results"] = results
// 创建日志
defer this.CreateLogInfo(codes.ServerCachePolicy_LogTestReading, params.CachePolicyId)
this.Success()
}

View File

@@ -0,0 +1,67 @@
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/nodes/nodeutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/messageconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"net/http"
"strconv"
)
type TestWriteAction struct {
actionutils.ParentAction
}
func (this *TestWriteAction) RunPost(params struct {
ClusterId int64
CachePolicyId int64
Key string
Value string
}) {
// 记录clusterId
this.AddCookie(&http.Cookie{
Name: "cache_cluster_id",
Value: strconv.FormatInt(params.ClusterId, 10),
})
cachePolicyResp, err := this.RPC().HTTPCachePolicyRPC().FindEnabledHTTPCachePolicyConfig(this.AdminContext(), &pb.FindEnabledHTTPCachePolicyConfigRequest{HttpCachePolicyId: params.CachePolicyId})
if err != nil {
this.ErrorPage(err)
return
}
cachePolicyJSON := cachePolicyResp.HttpCachePolicyJSON
if len(cachePolicyJSON) == 0 {
this.Fail("找不到要操作的缓存策略")
}
// 发送命令
msg := &messageconfigs.WriteCacheMessage{
CachePolicyJSON: cachePolicyJSON,
Key: params.Key,
Value: []byte(params.Value),
LifeSeconds: 3600,
}
results, err := nodeutils.SendMessageToCluster(this.AdminContext(), params.ClusterId, messageconfigs.MessageCodeWriteCache, msg, 10, false)
if err != nil {
this.ErrorPage(err)
return
}
isAllOk := true
for _, result := range results {
if !result.IsOK {
isAllOk = false
break
}
}
this.Data["isAllOk"] = isAllOk
this.Data["results"] = results
// 创建日志
defer this.CreateLogInfo(codes.ServerCachePolicy_LogTestWriting, params.CachePolicyId)
this.Success()
}

View File

@@ -0,0 +1,219 @@
package cache
import (
"encoding/json"
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/langs/codes"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/shared"
"github.com/iwind/TeaGo/actions"
)
type UpdateAction struct {
actionutils.ParentAction
}
func (this *UpdateAction) Init() {
this.Nav("", "", "update")
}
func (this *UpdateAction) RunGet(params struct {
CachePolicyId int64
}) {
configResp, err := this.RPC().HTTPCachePolicyRPC().FindEnabledHTTPCachePolicyConfig(this.AdminContext(), &pb.FindEnabledHTTPCachePolicyConfigRequest{HttpCachePolicyId: params.CachePolicyId})
if err != nil {
this.ErrorPage(err)
return
}
var configJSON = configResp.HttpCachePolicyJSON
if len(configJSON) == 0 {
this.NotFound("cachePolicy", params.CachePolicyId)
return
}
var cachePolicy = &serverconfigs.HTTPCachePolicy{}
err = json.Unmarshal(configJSON, cachePolicy)
if err != nil {
this.ErrorPage(err)
return
}
if cachePolicy.Type == serverconfigs.CachePolicyStorageFile && cachePolicy.Options != nil {
// fix min free size
{
_, ok := cachePolicy.Options["minFreeSize"]
if !ok {
cachePolicy.Options["minFreeSize"] = &shared.SizeCapacity{
Count: 0,
Unit: shared.SizeCapacityUnitGB,
}
}
}
// fix enableMMAP
{
_, ok := cachePolicy.Options["enableMMAP"]
if !ok {
cachePolicy.Options["enableMMAP"] = false
}
}
// fix enableIncompletePartialContent
{
_, ok := cachePolicy.Options["enableIncompletePartialContent"]
if !ok {
cachePolicy.Options["enableIncompletePartialContent"] = true
}
}
}
this.Data["cachePolicy"] = cachePolicy
// 其他选项
this.Data["types"] = serverconfigs.AllCachePolicyStorageTypes
this.Show()
}
func (this *UpdateAction) RunPost(params struct {
CachePolicyId int64
Name string
Type string
// file
FileDir string
FileMemoryCapacityJSON []byte
FileOpenFileCacheMax int
FileEnableSendfile bool
FileMinFreeSizeJSON []byte
CapacityJSON []byte
MaxSizeJSON []byte
SyncCompressionCache bool
FetchTimeoutJSON []byte
EnableMMAP bool
EnableIncompletePartialContent bool
Description string
IsOn bool
RefsJSON []byte
Must *actions.Must
}) {
// 创建日志
defer this.CreateLogInfo(codes.ServerCachePolicy_LogUpdateCachePolicy, params.CachePolicyId)
params.Must.
Field("name", params.Name).
Require("请输入策略名称")
// 校验选项
var options interface{}
switch params.Type {
case serverconfigs.CachePolicyStorageFile:
params.Must.
Field("fileDir", params.FileDir).
Require("请输入缓存目录")
var memoryCapacity = &shared.SizeCapacity{}
if len(params.FileMemoryCapacityJSON) > 0 {
err := json.Unmarshal(params.FileMemoryCapacityJSON, memoryCapacity)
if err != nil {
this.ErrorPage(err)
return
}
}
var openFileCacheConfig *serverconfigs.OpenFileCacheConfig
if params.FileOpenFileCacheMax > 0 {
openFileCacheConfig = &serverconfigs.OpenFileCacheConfig{
IsOn: true,
Max: params.FileOpenFileCacheMax,
}
}
var minFreeSize = &shared.SizeCapacity{}
var minFreeSizeJSON = params.FileMinFreeSizeJSON
if !utils.JSONIsNull(minFreeSizeJSON) {
_, err := utils.JSONDecodeConfig(minFreeSizeJSON, minFreeSize)
if err != nil {
this.ErrorPage(err)
return
}
if minFreeSize.Count < 0 {
minFreeSize.Count = 0
}
}
options = &serverconfigs.HTTPFileCacheStorage{
Dir: params.FileDir,
MemoryPolicy: &serverconfigs.HTTPCachePolicy{
Capacity: memoryCapacity,
},
OpenFileCache: openFileCacheConfig,
EnableSendfile: params.FileEnableSendfile,
MinFreeSize: minFreeSize,
EnableMMAP: params.EnableMMAP,
EnableIncompletePartialContent: params.EnableIncompletePartialContent,
}
case serverconfigs.CachePolicyStorageMemory:
options = &serverconfigs.HTTPMemoryCacheStorage{}
default:
this.Fail("请选择正确的缓存类型")
}
optionsJSON, err := json.Marshal(options)
if err != nil {
this.ErrorPage(err)
return
}
// 校验缓存条件
var refs = []*serverconfigs.HTTPCacheRef{}
if len(params.RefsJSON) > 0 {
err = json.Unmarshal(params.RefsJSON, &refs)
if err != nil {
this.Fail("缓存条件解析失败:" + err.Error())
}
for _, ref := range refs {
err = ref.Init()
if err != nil {
this.Fail("缓存条件校验失败:" + err.Error())
}
}
}
_, err = this.RPC().HTTPCachePolicyRPC().UpdateHTTPCachePolicy(this.AdminContext(), &pb.UpdateHTTPCachePolicyRequest{
HttpCachePolicyId: params.CachePolicyId,
IsOn: params.IsOn,
Name: params.Name,
Description: params.Description,
CapacityJSON: params.CapacityJSON,
MaxSizeJSON: params.MaxSizeJSON,
Type: params.Type,
OptionsJSON: optionsJSON,
SyncCompressionCache: params.SyncCompressionCache,
FetchTimeoutJSON: params.FetchTimeoutJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
// 修改缓存条件
_, err = this.RPC().HTTPCachePolicyRPC().UpdateHTTPCachePolicyRefs(this.AdminContext(), &pb.UpdateHTTPCachePolicyRefsRequest{
HttpCachePolicyId: params.CachePolicyId,
RefsJSON: params.RefsJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,35 @@
// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
package cache
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
)
type UpdateRefsAction struct {
actionutils.ParentAction
}
func (this *UpdateRefsAction) Init() {
this.Nav("", "", "")
}
func (this *UpdateRefsAction) RunPost(params struct {
CachePolicyId int64
RefsJSON []byte
}) {
// 修改缓存条件
if params.CachePolicyId > 0 && len(params.RefsJSON) > 0 {
_, err := this.RPC().HTTPCachePolicyRPC().UpdateHTTPCachePolicyRefs(this.AdminContext(), &pb.UpdateHTTPCachePolicyRefsRequest{
HttpCachePolicyId: params.CachePolicyId,
RefsJSON: params.RefsJSON,
})
if err != nil {
this.ErrorPage(err)
return
}
}
this.Success()
}