endpoint.go 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package server
  2. import (
  3. "errors"
  4. "time"
  5. "github.com/gin-gonic/gin"
  6. "github.com/langgenius/dify-plugin-daemon/internal/db"
  7. "github.com/langgenius/dify-plugin-daemon/internal/service"
  8. "github.com/langgenius/dify-plugin-daemon/internal/types/app"
  9. "github.com/langgenius/dify-plugin-daemon/internal/types/exception"
  10. "github.com/langgenius/dify-plugin-daemon/internal/types/models"
  11. "github.com/langgenius/dify-plugin-daemon/internal/utils/log"
  12. "github.com/langgenius/dify-plugin-daemon/pkg/entities/plugin_entities"
  13. )
  14. // DifyPlugin supports register and use endpoint to improve the plugin's functionality
  15. // you can use it to do some magics, looking forward to your imagination, Ciallo~(∠·ω< )⌒
  16. // - Yeuoly
  17. // EndpointHandler is a function type that can be used to handle endpoint requests
  18. type EndpointHandler func(ctx *gin.Context, hookId string, maxExecutionTime time.Duration, path string)
  19. func (app *App) Endpoint(config *app.Config) func(c *gin.Context) {
  20. return func(c *gin.Context) {
  21. hookId := c.Param("hook_id")
  22. path := c.Param("path")
  23. if app.endpointHandler != nil {
  24. app.endpointHandler(c, hookId, time.Duration(config.PluginMaxExecutionTimeout)*time.Second, path)
  25. } else {
  26. app.EndpointHandler(c, hookId, time.Duration(config.PluginMaxExecutionTimeout)*time.Second, path)
  27. }
  28. }
  29. }
  30. func (app *App) EndpointHandler(ctx *gin.Context, hookId string, maxExecutionTime time.Duration, path string) {
  31. endpoint, err := db.GetCache[models.Endpoint](&db.GetCachePayload[models.Endpoint]{
  32. Getter: func() (*models.Endpoint, error) {
  33. v, err := db.GetOne[models.Endpoint](
  34. db.Equal("hook_id", hookId),
  35. )
  36. return &v, err
  37. },
  38. CacheKey: []db.KeyValuePair{
  39. {Key: "hook_id", Val: hookId},
  40. },
  41. })
  42. if err == db.ErrDatabaseNotFound {
  43. ctx.JSON(404, exception.BadRequestError(errors.New("endpoint not found")).ToResponse())
  44. return
  45. }
  46. if err != nil {
  47. log.Error("get endpoint error %v", err)
  48. ctx.JSON(500, exception.InternalServerError(errors.New("internal server error")).ToResponse())
  49. return
  50. }
  51. // get plugin installation
  52. pluginInstallation, err := db.GetCache[models.PluginInstallation](
  53. &db.GetCachePayload[models.PluginInstallation]{
  54. Getter: func() (*models.PluginInstallation, error) {
  55. v, err := db.GetOne[models.PluginInstallation](
  56. db.Equal("plugin_id", endpoint.PluginID),
  57. db.Equal("tenant_id", endpoint.TenantID),
  58. )
  59. return &v, err
  60. },
  61. CacheKey: []db.KeyValuePair{
  62. {Key: "plugin_id", Val: endpoint.PluginID},
  63. {Key: "tenant_id", Val: endpoint.TenantID},
  64. },
  65. })
  66. if err != nil {
  67. ctx.JSON(404, exception.BadRequestError(errors.New("plugin installation not found")).ToResponse())
  68. return
  69. }
  70. pluginUniqueIdentifier, err := plugin_entities.NewPluginUniqueIdentifier(
  71. pluginInstallation.PluginUniqueIdentifier,
  72. )
  73. if err != nil {
  74. ctx.JSON(400, exception.UniqueIdentifierError(
  75. errors.New("invalid plugin unique identifier"),
  76. ).ToResponse())
  77. return
  78. }
  79. // check if plugin exists in current node
  80. if ok, originalError := app.cluster.IsPluginOnCurrentNode(pluginUniqueIdentifier); !ok {
  81. app.redirectPluginInvokeByPluginIdentifier(ctx, pluginUniqueIdentifier, originalError)
  82. } else {
  83. service.Endpoint(ctx, endpoint, pluginInstallation, maxExecutionTime, path)
  84. }
  85. }