From 125965dabd0466bbb8446960b5c69ecc25f79a44 Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Thu, 16 Jan 2025 16:36:06 +0800 Subject: [PATCH 1/6] update build script --- scripts/Dockerfile | 4 ++-- scripts/docker_build.sh | 2 +- scripts/resource/docker_run.sh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/Dockerfile b/scripts/Dockerfile index 71b5c4e3..6e712a47 100755 --- a/scripts/Dockerfile +++ b/scripts/Dockerfile @@ -8,8 +8,8 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone ARG APP -ENV NSQ_ADDR=nsq:4150 -ENV NSQ_TOPIC_PREFIX=apipark +ENV NSQ_ADDR=${APP}-nsq:4150 +ENV NSQ_TOPIC_PREFIX=${APP} RUN mkdir -p /${APP} diff --git a/scripts/docker_build.sh b/scripts/docker_build.sh index 2a43ba84..5c51a097 100755 --- a/scripts/docker_build.sh +++ b/scripts/docker_build.sh @@ -17,7 +17,7 @@ source ./scripts/common.sh APP="apipark" -mkdir -p scripts/cmd/ && cp cmd/${APP} scripts/cmd/ +mkdir -p scripts/cmd/ && cp cmd/${APP} scripts/cmd/ && cp cmd/apipark_ai_event_listen scripts/cmd/ VERSION=$(gen_version) diff --git a/scripts/resource/docker_run.sh b/scripts/resource/docker_run.sh index f8c56e54..255f7243 100755 --- a/scripts/resource/docker_run.sh +++ b/scripts/resource/docker_run.sh @@ -27,7 +27,7 @@ echo -e " - $s" >> config.yml done echo -e "nsq:" >> config.yml echo -e " addr: ${NSQ_ADDR}" >> config.yml -echo -e " topic: ${NSQ_TOPIC}" >> config.yml +echo -e " topic_prefix: ${NSQ_TOPIC_PREFIX}" >> config.yml echo -e "port: 8288" >> config.yml echo -e "error_log:" >> config.yml echo -e " dir: ${ERROR_DIR}" >> config.yml From 38ca9815ba8a1580a7c223ed921176ed095b16b4 Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Thu, 16 Jan 2025 16:36:25 +0800 Subject: [PATCH 2/6] update provider status default value --- stores/ai/model.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stores/ai/model.go b/stores/ai/model.go index 1f1ee178..b25f4c29 100644 --- a/stores/ai/model.go +++ b/stores/ai/model.go @@ -8,7 +8,7 @@ type Provider struct { Name string `gorm:"type:varchar(100);not null;column:name;comment:name"` DefaultLLM string `gorm:"type:varchar(255);not null;column:default_llm;comment:默认模型ID"` Config string `gorm:"type:text;not null;column:config;comment:配置信息"` - Status int `gorm:"type:tinyint(1);not null;column:status;comment:状态,0:停用;1:启用,2:异常"` + Status int `gorm:"type:tinyint(1);not null;column:status;comment:状态,0:停用;1:启用,2:异常;default:1"` Priority int `gorm:"type:int;not null;column:priority;comment:优先级,值越小优先级越高"` Creator string `gorm:"size:36;not null;column:creator;comment:创建人;index:creator" aovalue:"creator"` // 创建人 Updater string `gorm:"size:36;not null;column:updater;comment:更新人;index:updater" aovalue:"updater"` // 更新人 From 1140e43d6772828f6da5555da70334611e3d14f1 Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Thu, 16 Jan 2025 18:53:58 +0800 Subject: [PATCH 3/6] update init plugin config --- gateway/apinto/plugin/apinto_plugin.yml | 2 +- resources/plugin/plugin.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gateway/apinto/plugin/apinto_plugin.yml b/gateway/apinto/plugin/apinto_plugin.yml index 4bd3765a..b3c3c6d8 100644 --- a/gateway/apinto/plugin/apinto_plugin.yml +++ b/gateway/apinto/plugin/apinto_plugin.yml @@ -28,7 +28,7 @@ b: "subscription_service:#{application}" response: status_code: 403 - content_typ: "text/plan" + content_type: "text/plan" charset: "utf-8" body: "Forbidden" diff --git a/resources/plugin/plugin.yml b/resources/plugin/plugin.yml index f731a53f..73aa40bb 100644 --- a/resources/plugin/plugin.yml +++ b/resources/plugin/plugin.yml @@ -1,4 +1,4 @@ -version: v7 +version: v8 sort: - "access_log" - "monitor" @@ -41,7 +41,7 @@ plugin: b: "subscription_service:#{application}" response: status_code: 403 - content_typ: "text/plan" + content_type: "text/plan" charset: "utf-8" body: "Forbidden" From 1adf8c890fc46c62bd2ac1093b77bd2e77597fa6 Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Fri, 17 Jan 2025 10:38:35 +0800 Subject: [PATCH 4/6] fix: ai event handler read event error --- app/ai-event-handler/nsq.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/app/ai-event-handler/nsq.go b/app/ai-event-handler/nsq.go index f8e9e03c..b656ba57 100644 --- a/app/ai-event-handler/nsq.go +++ b/app/ai-event-handler/nsq.go @@ -3,6 +3,7 @@ package main import ( "context" "encoding/json" + "fmt" "log" "strings" "time" @@ -27,8 +28,8 @@ func init() { } type NSQConfig struct { - Addr string `json:"addr"` - TopicPrefix string `json:"topic_prefix"` + Addr string `json:"addr" yaml:"addr"` + TopicPrefix string `json:"topic_prefix" yaml:"topic_prefix"` } // 定义 NSQ 消息结构 @@ -78,6 +79,11 @@ func convertInt(value interface{}) int { } } +func genAIKey(key string, provider string) string { + keys := strings.Split(key, "@") + return strings.TrimSuffix(keys[0], fmt.Sprintf("-%s", provider)) +} + // HandleMessage 处理从 NSQ 读取的消息 func (h *NSQHandler) HandleMessage(message *nsq.Message) error { log.Printf("Received message: %s", string(message.Body)) @@ -104,8 +110,7 @@ func (h *NSQHandler) HandleMessage(message *nsq.Message) error { finalStatus := &AIProviderStatus{} for _, s := range data.AI.ProviderStats { status := ToKeyStatus(s.Status).Int() - keys := strings.Split(s.Key, "@") - key := keys[0] + key := genAIKey(s.Key, s.Provider) err = h.aiKeyService.Save(ctx, key, &ai_key.Edit{ Status: &status, }) @@ -128,8 +133,9 @@ func (h *NSQHandler) HandleMessage(message *nsq.Message) error { finalStatus = &s } if finalStatus != nil { - keys := strings.Split(finalStatus.Key, "@") - err = h.aiKeyService.IncrUseToken(ctx, keys[0], convertInt(data.AI.TotalToken)) + //keys := strings.Split(finalStatus.Key, "@") + key := genAIKey(finalStatus.Key, finalStatus.Provider) + err = h.aiKeyService.IncrUseToken(ctx, key, convertInt(data.AI.TotalToken)) if err != nil { log.Printf("Failed to increment AI key token: %v", err) return err From ad2d62d13b2ca77380c98dffd4022caa47cc7cdd Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Fri, 17 Jan 2025 11:34:34 +0800 Subject: [PATCH 5/6] fix: Nsq returns no error directly after parsing JSON exceptionNsq returns no error directly after parsing JSON exception --- app/ai-event-handler/nsq.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/ai-event-handler/nsq.go b/app/ai-event-handler/nsq.go index b656ba57..3f891490 100644 --- a/app/ai-event-handler/nsq.go +++ b/app/ai-event-handler/nsq.go @@ -93,14 +93,14 @@ func (h *NSQHandler) HandleMessage(message *nsq.Message) error { err := json.Unmarshal(message.Body, &data) if err != nil { log.Printf("Failed to unmarshal message: %v", err) - return err + return nil } // 将时间字符串转换为 time.Time timestamp, err := time.Parse(time.RFC3339, data.TimeISO8601) if err != nil { log.Printf("Failed to parse timestamp: %v", err) - return err + return nil } day := time.Date(timestamp.Year(), timestamp.Month(), timestamp.Day(), 0, 0, 0, 0, timestamp.Location()) @@ -116,7 +116,7 @@ func (h *NSQHandler) HandleMessage(message *nsq.Message) error { }) if err != nil { log.Printf("Failed to save AI key: %v", err) - return err + return nil } if s.Provider != data.AI.Provider { @@ -138,7 +138,7 @@ func (h *NSQHandler) HandleMessage(message *nsq.Message) error { err = h.aiKeyService.IncrUseToken(ctx, key, convertInt(data.AI.TotalToken)) if err != nil { log.Printf("Failed to increment AI key token: %v", err) - return err + return nil } } @@ -157,7 +157,7 @@ func (h *NSQHandler) HandleMessage(message *nsq.Message) error { }) if err != nil { log.Printf("Failed to call AI API: %v", err) - return err + return nil } log.Printf("Message processed and saved to MySQL: %+v", data) From 0a864aea41fa7c53943d4e2e995a283f93d84e34 Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Fri, 17 Jan 2025 16:03:09 +0800 Subject: [PATCH 6/6] add openapi --- init.go | 1 + plugins/openapi/authorization.go | 18 +++++++++++++ plugins/openapi/check.go | 45 ++++++++++++++++++++++++++++++++ plugins/openapi/driver.go | 19 ++++++++++++++ plugins/openapi/plugin.go | 33 +++++++++++++++++++++++ 5 files changed, 116 insertions(+) create mode 100644 plugins/openapi/authorization.go create mode 100644 plugins/openapi/check.go create mode 100644 plugins/openapi/driver.go create mode 100644 plugins/openapi/plugin.go diff --git a/init.go b/init.go index 74592a3a..af7b6ca9 100644 --- a/init.go +++ b/init.go @@ -5,6 +5,7 @@ import ( _ "github.com/APIParkLab/APIPark/frontend" _ "github.com/APIParkLab/APIPark/gateway/apinto" _ "github.com/APIParkLab/APIPark/plugins/core" + _ "github.com/APIParkLab/APIPark/plugins/openapi" _ "github.com/APIParkLab/APIPark/plugins/permit" _ "github.com/APIParkLab/APIPark/plugins/publish_flow" _ "github.com/APIParkLab/APIPark/resources/locale" diff --git a/plugins/openapi/authorization.go b/plugins/openapi/authorization.go new file mode 100644 index 00000000..d6f37e8a --- /dev/null +++ b/plugins/openapi/authorization.go @@ -0,0 +1,18 @@ +package openapi + +import ( + "net/http" + + "github.com/eolinker/go-common/pm3" +) + +func (p *plugin) appAuthorizationApis() []pm3.Api { + return []pm3.Api{ + pm3.CreateApiWidthDoc(http.MethodPost, "/openapi/v1/app/authorization", []string{"context", "query:app", "body"}, []string{"authorization"}, p.authorizationController.AddAuthorization), + pm3.CreateApiWidthDoc(http.MethodPut, "/openapi/v1/app/authorization", []string{"context", "query:app", "query:authorization", "body"}, []string{"authorization"}, p.authorizationController.EditAuthorization), + pm3.CreateApiWidthDoc(http.MethodDelete, "/openapi/v1/app/authorization", []string{"context", "query:app", "query:authorization"}, nil, p.authorizationController.DeleteAuthorization), + pm3.CreateApiWidthDoc(http.MethodGet, "/openapi/v1/app/authorization", []string{"context", "query:app", "query:authorization"}, []string{"authorization"}, p.authorizationController.Info), + pm3.CreateApiWidthDoc(http.MethodGet, "/openapi/v1/app/authorizations", []string{"context", "query:app"}, []string{"authorizations"}, p.authorizationController.Authorizations), + pm3.CreateApiWidthDoc(http.MethodGet, "/openapi/v1/app/authorization/details", []string{"context", "query:app", "query:authorization"}, []string{"details"}, p.authorizationController.Detail), + } +} diff --git a/plugins/openapi/check.go b/plugins/openapi/check.go new file mode 100644 index 00000000..4f5f50f7 --- /dev/null +++ b/plugins/openapi/check.go @@ -0,0 +1,45 @@ +package openapi + +import ( + "strings" + + "github.com/eolinker/eosc/env" + + "github.com/gin-gonic/gin" +) + +var ( + defaultAPIKey = "37eb0ebf" + openCheck = newOpenapiCheck() +) + +type openapiCheck struct { + apikey string +} + +func newOpenapiCheck() *openapiCheck { + apikey, has := env.GetEnv("API_KEY") + if !has { + apikey = defaultAPIKey + } + return &openapiCheck{apikey: apikey} +} + +func (o *openapiCheck) Check(method string, path string) (bool, []gin.HandlerFunc) { + if strings.HasPrefix(path, "/openapi/") { + return true, []gin.HandlerFunc{o.Handler} + } + return false, nil +} + +func (o *openapiCheck) Sort() int { + return -1 +} + +func (o *openapiCheck) Handler(ginCtx *gin.Context) { + authorization := ginCtx.GetHeader("Authorization") + if authorization == "" { + ginCtx.AbortWithStatusJSON(403, gin.H{"code": -8, "msg": "invalid token", "success": "fail"}) + return + } +} diff --git a/plugins/openapi/driver.go b/plugins/openapi/driver.go new file mode 100644 index 00000000..9e9997a6 --- /dev/null +++ b/plugins/openapi/driver.go @@ -0,0 +1,19 @@ +package openapi + +import ( + "github.com/eolinker/go-common/autowire" + "github.com/eolinker/go-common/pm3" +) + +func init() { + pm3.Register("openapi", new(Driver)) +} + +type Driver struct { +} + +func (d *Driver) Create() (pm3.IPlugin, error) { + p := new(plugin) + autowire.Autowired(p) + return p, nil +} diff --git a/plugins/openapi/plugin.go b/plugins/openapi/plugin.go new file mode 100644 index 00000000..3082fb84 --- /dev/null +++ b/plugins/openapi/plugin.go @@ -0,0 +1,33 @@ +package openapi + +import ( + application_authorization "github.com/APIParkLab/APIPark/controller/application-authorization" + "github.com/eolinker/go-common/pm3" +) + +var ( + _ pm3.IPlugin = (*plugin)(nil) + _ pm3.IPluginMiddleware = (*plugin)(nil) +) + +type plugin struct { + apis []pm3.Api + authorizationController application_authorization.IAuthorizationController `autowired:""` +} + +func (p *plugin) Middlewares() []pm3.IMiddleware { + return []pm3.IMiddleware{ + openCheck, + } +} + +func (p *plugin) APis() []pm3.Api { + return p.apis +} + +func (p *plugin) Name() string { + return "openapi" +} +func (p *plugin) OnComplete() { + p.apis = p.appAuthorizationApis() +}