Yeuoly месяцев назад: 11
Родитель
Сommit
99d196c9bd

+ 6 - 5
cmd/server/main.go

@@ -40,9 +40,10 @@ func setDefault(config *app.Config) {
 	setDefaultInt(&config.DifyInvocationConnectionIdleTimeout, 120)
 	setDefaultInt(&config.PluginRemoteInstallServerEventLoopNums, 8)
 	setDefaultInt(&config.PluginRemoteInstallingMaxConn, 128)
-	settDefaultBool(&config.PluginRemoteInstallingEnabled, true)
-	settDefaultString(&config.DBSslMode, "disable")
-	settDefaultString(&config.ProcessCachingPath, "/tmp/dify-plugin-daemon-subprocesses")
+	setDefaultBool(&config.PluginRemoteInstallingEnabled, true)
+	setDefaultBool(&config.PluginWebhookEnabled, true)
+	setDefaultString(&config.DBSslMode, "disable")
+	setDefaultString(&config.ProcessCachingPath, "/tmp/dify-plugin-daemon-subprocesses")
 }
 
 func setDefaultInt[T constraints.Integer](value *T, defaultValue T) {
@@ -51,13 +52,13 @@ func setDefaultInt[T constraints.Integer](value *T, defaultValue T) {
 	}
 }
 
-func settDefaultString(value *string, defaultValue string) {
+func setDefaultString(value *string, defaultValue string) {
 	if *value == "" {
 		*value = defaultValue
 	}
 }
 
-func settDefaultBool(value *bool, defaultValue bool) {
+func setDefaultBool(value *bool, defaultValue bool) {
 	if !*value {
 		*value = defaultValue
 	}

+ 3 - 6
internal/cluster/vote_test.go

@@ -2,12 +2,12 @@ package cluster
 
 import (
 	"fmt"
-	"net"
 	"sync"
 	"testing"
 	"time"
 
 	"github.com/gin-gonic/gin"
+	"github.com/langgenius/dify-plugin-daemon/internal/utils/network"
 )
 
 func createSimulationHealthCheckSever() (uint16, error) {
@@ -18,13 +18,10 @@ func createSimulationHealthCheckSever() (uint16, error) {
 		c.JSON(200, gin.H{"status": "ok"})
 	})
 
-	listener, err := net.Listen("tcp", ":0")
+	port, err := network.GetRandomPort()
 	if err != nil {
-		return 0, fmt.Errorf("failed to get a random port: %s", err.Error())
+		return 0, err
 	}
-	listener.Close()
-
-	port := listener.Addr().(*net.TCPAddr).Port
 
 	go func() {
 		router.Run(fmt.Sprintf(":%d", port))

+ 5 - 8
internal/core/plugin_manager/remote_manager/server_test.go

@@ -11,27 +11,24 @@ import (
 	"github.com/langgenius/dify-plugin-daemon/internal/types/app"
 	"github.com/langgenius/dify-plugin-daemon/internal/types/entities/plugin_entities"
 	"github.com/langgenius/dify-plugin-daemon/internal/utils/cache"
+	"github.com/langgenius/dify-plugin-daemon/internal/utils/network"
 	"github.com/langgenius/dify-plugin-daemon/internal/utils/parser"
 )
 
 func preparePluginServer(t *testing.T) (*RemotePluginServer, uint16) {
-	// generate a random port
-	listener, err := net.Listen("tcp", ":0")
+	port, err := network.GetRandomPort()
 	if err != nil {
-		t.Errorf("failed to get a random port: %s", err.Error())
+		t.Errorf("failed to get random port: %s", err.Error())
 		return nil, 0
 	}
-	listener.Close()
-
-	port := listener.Addr().(*net.TCPAddr).Port
 
 	// start plugin server
 	return NewRemotePluginServer(&app.Config{
 		PluginRemoteInstallingHost:             "0.0.0.0",
-		PluginRemoteInstallingPort:             uint16(port),
+		PluginRemoteInstallingPort:             port,
 		PluginRemoteInstallingMaxConn:          1,
 		PluginRemoteInstallServerEventLoopNums: 8,
-	}), uint16(port)
+	}), port
 }
 
 // TestLaunchAndClosePluginServer tests the launch and close of the plugin server

+ 2 - 0
internal/server/app.go

@@ -6,4 +6,6 @@ import (
 
 type App struct {
 	cluster *cluster.Cluster
+
+	webhook_handler WebhookHandler
 }

+ 0 - 22
internal/server/controllers/webhook.go

@@ -1,23 +1 @@
 package controllers
-
-import (
-	"github.com/gin-gonic/gin"
-)
-
-func WebhookHead(c *gin.Context) {
-}
-
-func WebhookGet(c *gin.Context) {
-}
-
-func WebhookPost(c *gin.Context) {
-}
-
-func WebhookPut(c *gin.Context) {
-}
-
-func WebhookDelete(c *gin.Context) {
-}
-
-func WebhookOptions(c *gin.Context) {
-}

+ 26 - 8
internal/server/http.go

@@ -1,14 +1,17 @@
 package server
 
 import (
+	"context"
 	"fmt"
+	"net/http"
 
 	"github.com/gin-gonic/gin"
 	"github.com/langgenius/dify-plugin-daemon/internal/server/controllers"
 	"github.com/langgenius/dify-plugin-daemon/internal/types/app"
+	"github.com/langgenius/dify-plugin-daemon/internal/utils/log"
 )
 
-func (app *App) server(config *app.Config) {
+func (app *App) server(config *app.Config) func() {
 	engine := gin.Default()
 
 	engine.GET("/health/check", controllers.HealthCheck)
@@ -84,13 +87,28 @@ func (app *App) server(config *app.Config) {
 	}
 
 	if config.PluginWebhookEnabled {
-		engine.HEAD("/webhook/:hook_id/*path", controllers.WebhookHead)
-		engine.POST("/webhook/:hook_id/*path", controllers.WebhookPost)
-		engine.GET("/webhook/:hook_id/*path", controllers.WebhookGet)
-		engine.PUT("/webhook/:hook_id/*path", controllers.WebhookPut)
-		engine.DELETE("/webhook/:hook_id/*path", controllers.WebhookDelete)
-		engine.OPTIONS("/webhook/:hook_id/*path", controllers.WebhookOptions)
+		engine.HEAD("/webhook/:hook_id/*path", app.Webhook())
+		engine.POST("/webhook/:hook_id/*path", app.Webhook())
+		engine.GET("/webhook/:hook_id/*path", app.Webhook())
+		engine.PUT("/webhook/:hook_id/*path", app.Webhook())
+		engine.DELETE("/webhook/:hook_id/*path", app.Webhook())
+		engine.OPTIONS("/webhook/:hook_id/*path", app.Webhook())
 	}
 
-	engine.Run(fmt.Sprintf(":%d", config.ServerPort))
+	srv := &http.Server{
+		Addr:    fmt.Sprintf(":%d", config.ServerPort),
+		Handler: engine,
+	}
+
+	go func() {
+		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+			log.Panic("listen: %s\n", err)
+		}
+	}()
+
+	return func() {
+		if err := srv.Shutdown(context.Background()); err != nil {
+			log.Panic("Server Shutdown: %s\n", err)
+		}
+	}
 }

+ 3 - 0
internal/server/server.go

@@ -29,4 +29,7 @@ func (a *App) Run(config *app.Config) {
 
 	// start http server
 	a.server(config)
+
+	// block
+	select {}
 }

+ 32 - 0
internal/server/webhook.go

@@ -0,0 +1,32 @@
+package server
+
+import (
+	"fmt"
+
+	"github.com/gin-gonic/gin"
+)
+
+// DifyPlugin supports register and use webhook to improve the plugin's functionality
+// you can use it to do some magic things, look forward to your imagination Ciallo~(∠·ω< )⌒
+// - Yeuoly
+
+// WebhookHandler is a function type that can be used to handle webhook requests
+type WebhookHandler func(hook_id string, path string)
+
+func (app *App) Webhook() func(c *gin.Context) {
+	return func(c *gin.Context) {
+		hook_id := c.Param("hook_id")
+		path := c.Param("path")
+
+		if app.webhook_handler != nil {
+			app.webhook_handler(hook_id, path)
+		} else {
+			app.WebhookHandler(hook_id, path)
+		}
+	}
+}
+
+func (app *App) WebhookHandler(hook_id string, path string) {
+	fmt.Println(hook_id)
+	fmt.Println(path)
+}

+ 58 - 0
internal/server/webhook_test.go

@@ -0,0 +1,58 @@
+package server
+
+import (
+	"net/http"
+	"strconv"
+	"testing"
+
+	"github.com/langgenius/dify-plugin-daemon/internal/types/app"
+	"github.com/langgenius/dify-plugin-daemon/internal/utils/network"
+)
+
+func TestWebhookParams(t *testing.T) {
+	port, err := network.GetRandomPort()
+	if err != nil {
+		t.Errorf("failed to get random port: %s", err.Error())
+		return
+	}
+
+	global_hook_id := ""
+	global_hook_path := ""
+
+	handler := func(hook_id string, path string) {
+		global_hook_id = hook_id
+		global_hook_path = path
+	}
+
+	app_pointer := &App{
+		webhook_handler: handler,
+	}
+	cancel := app_pointer.server(&app.Config{
+		ServerPort:           port,
+		PluginWebhookEnabled: true,
+	})
+	defer cancel()
+
+	// test webhook params
+	client := &http.Client{}
+	req, err := http.NewRequest("POST", "http://localhost:"+strconv.Itoa(int(port))+"/webhook/1111/v1/chat/completions", nil)
+	if err != nil {
+		t.Errorf("failed to create request: %s", err.Error())
+		return
+	}
+	_, err = client.Do(req)
+	if err != nil {
+		t.Errorf("failed to send request: %s", err.Error())
+		return
+	}
+
+	if global_hook_id != "1111" {
+		t.Errorf("hook id not match: %s", global_hook_id)
+		return
+	}
+
+	if global_hook_path != "/v1/chat/completions" {
+		t.Errorf("hook path not match: %s", global_hook_path)
+		return
+	}
+}

+ 1 - 0
internal/service/webhook.go

@@ -0,0 +1 @@
+package service

+ 3 - 3
internal/types/app/config.go

@@ -7,7 +7,7 @@ import (
 )
 
 type Config struct {
-	ServerPort int16 `envconfig:"SERVER_PORT" validate:"required"`
+	ServerPort uint16 `envconfig:"SERVER_PORT" validate:"required"`
 
 	PluginInnerApiKey string `envconfig:"PLUGIN_INNER_API_KEY" validate:"required"`
 	PluginInnerApiURL string `envconfig:"PLUGIN_INNER_API_URL" validate:"required"`
@@ -28,13 +28,13 @@ type Config struct {
 	RoutinePoolSize int `envconfig:"ROUTINE_POOL_SIZE" validate:"required"`
 
 	RedisHost string `envconfig:"REDIS_HOST" validate:"required"`
-	RedisPort int16  `envconfig:"REDIS_PORT" validate:"required"`
+	RedisPort uint16 `envconfig:"REDIS_PORT" validate:"required"`
 	RedisPass string `envconfig:"REDIS_PASS" validate:"required"`
 
 	DBUsername string `envconfig:"DB_USERNAME" validate:"required"`
 	DBPassword string `envconfig:"DB_PASSWORD" validate:"required"`
 	DBHost     string `envconfig:"DB_HOST" validate:"required"`
-	DBPort     int16  `envconfig:"DB_PORT" validate:"required"`
+	DBPort     uint16 `envconfig:"DB_PORT" validate:"required"`
 	DBDatabase string `envconfig:"DB_DATABASE" validate:"required"`
 	DBSslMode  string `envconfig:"DB_SSL_MODE" validate:"required,oneof=disable require"`
 

+ 15 - 0
internal/utils/network/random_port.go

@@ -0,0 +1,15 @@
+package network
+
+import "net"
+
+func GetRandomPort() (uint16, error) {
+	// generate a random port
+	listener, err := net.Listen("tcp", ":0")
+	if err != nil {
+		return 0, err
+	}
+	listener.Close()
+
+	port := listener.Addr().(*net.TCPAddr).Port
+	return uint16(port), nil
+}