From c760af7810410d9167098c6902938d942f71366e Mon Sep 17 00:00:00 2001 From: Naoki Takezoe Date: Sat, 11 Mar 2017 11:19:57 +0900 Subject: [PATCH 01/23] Add adapter filter for plugin controllers --- build.sbt | 2 +- src/main/scala/ScalatraBootstrap.scala | 5 ++- .../core/servlet/PluginControllerFilter.scala | 34 +++++++++++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 src/main/scala/gitbucket/core/servlet/PluginControllerFilter.scala diff --git a/build.sbt b/build.sbt index d219ff3a2..d3532de1e 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ val Organization = "io.github.gitbucket" val Name = "gitbucket" -val GitBucketVersion = "4.10.0" +val GitBucketVersion = "4.11.0-SNAPSHOT" val ScalatraVersion = "2.5.0" val JettyVersion = "9.3.9.v20160517" diff --git a/src/main/scala/ScalatraBootstrap.scala b/src/main/scala/ScalatraBootstrap.scala index 949bf80d9..c767f591c 100644 --- a/src/main/scala/ScalatraBootstrap.scala +++ b/src/main/scala/ScalatraBootstrap.scala @@ -31,9 +31,8 @@ class ScalatraBootstrap extends LifeCycle with SystemSettingsService { // Register controllers context.mount(new AnonymousAccessController, "/*") - PluginRegistry().getControllers.foreach { case (controller, path) => - context.mount(controller, path) - } + context.addFilter("pluginControllerFilter", new PluginControllerFilter) + context.getFilterRegistration("pluginControllerFilter").addMappingForUrlPatterns(EnumSet.allOf(classOf[DispatcherType]), true, "/*") context.mount(new IndexController, "/") context.mount(new ApiController, "/api/v3") diff --git a/src/main/scala/gitbucket/core/servlet/PluginControllerFilter.scala b/src/main/scala/gitbucket/core/servlet/PluginControllerFilter.scala new file mode 100644 index 000000000..95060f00c --- /dev/null +++ b/src/main/scala/gitbucket/core/servlet/PluginControllerFilter.scala @@ -0,0 +1,34 @@ +package gitbucket.core.servlet + +import javax.servlet._ +import javax.servlet.http.HttpServletRequest + +import gitbucket.core.plugin.PluginRegistry + +class PluginControllerFilter extends Filter { + + override def init(filterConfig: FilterConfig): Unit = { + PluginRegistry().getControllers().foreach { case (controller, _) => + controller.init(filterConfig) + } + } + + override def destroy(): Unit = { + PluginRegistry().getControllers().foreach { case (controller, _) => + controller.destroy() + } + } + + override def doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain): Unit = { + val controller = PluginRegistry().getControllers().find { case (_, path) => + val requestUri = request.asInstanceOf[HttpServletRequest].getRequestURI + path.endsWith("/*") && requestUri.startsWith(path.replaceFirst("/\\*$", "/")) + } + + controller.map { case (controller, _) => + controller.doFilter(request, response, chain) + }.getOrElse{ + chain.doFilter(request, response) + } + } +} From 7e7e45e794de76ac0994f8a000a81038afe96dd9 Mon Sep 17 00:00:00 2001 From: Naoki Takezoe Date: Sat, 11 Mar 2017 12:13:59 +0900 Subject: [PATCH 02/23] Add the plugin reload button to the plugin list page --- .../controller/SystemSettingsController.scala | 7 ++++++- .../gitbucket/core/plugin/PluginRegistory.scala | 16 ++++++++++++---- .../core/servlet/PluginControllerFilter.scala | 9 ++++++--- .../gitbucket/core/admin/plugins.scala.html | 7 +++++-- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala index ac2fbff14..e47d0fc89 100644 --- a/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala +++ b/src/main/scala/gitbucket/core/controller/SystemSettingsController.scala @@ -181,9 +181,14 @@ trait SystemSettingsControllerBase extends AccountManagementControllerBase { }) get("/admin/plugins")(adminOnly { - html.plugins(PluginRegistry().getPlugins()) + html.plugins(PluginRegistry().getPlugins(), flash.get("info")) }) + post("/admin/plugins/_reload")(adminOnly { + PluginRegistry.reload(request.getServletContext(), loadSystemSettings(), request2Session(request).conn) + flash += "info" -> "All plugins are reloaded." + redirect("/admin/plugins") + }) get("/admin/users")(adminOnly { val includeRemoved = params.get("includeRemoved").map(_.toBoolean).getOrElse(false) diff --git a/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala b/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala index 7ba1026e6..76c360233 100644 --- a/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala +++ b/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala @@ -155,17 +155,26 @@ object PluginRegistry { private val logger = LoggerFactory.getLogger(classOf[PluginRegistry]) - private val instance = new PluginRegistry() + private var instance = new PluginRegistry() /** * Returns the PluginRegistry singleton instance. */ def apply(): PluginRegistry = instance + /** + * Reload all plugins. + */ + def reload(context: ServletContext, settings: SystemSettings, conn: java.sql.Connection): Unit = synchronized { + shutdown(context, settings) + instance = new PluginRegistry() + initialize(context, settings, conn) + } + /** * Initializes all installed plugins. */ - def initialize(context: ServletContext, settings: SystemSettings, conn: java.sql.Connection): Unit = { + def initialize(context: ServletContext, settings: SystemSettings, conn: java.sql.Connection): Unit = synchronized { val pluginDir = new File(PluginHome) val manager = new JDBCVersionManager(conn) @@ -207,7 +216,7 @@ object PluginRegistry { } } - def shutdown(context: ServletContext, settings: SystemSettings): Unit = { + def shutdown(context: ServletContext, settings: SystemSettings): Unit = synchronized { instance.getPlugins().foreach { pluginInfo => try { pluginInfo.pluginClass.shutdown(instance, context, settings) @@ -219,7 +228,6 @@ object PluginRegistry { } } - } case class Link(id: String, label: String, path: String, icon: Option[String] = None) diff --git a/src/main/scala/gitbucket/core/servlet/PluginControllerFilter.scala b/src/main/scala/gitbucket/core/servlet/PluginControllerFilter.scala index 95060f00c..442841b1b 100644 --- a/src/main/scala/gitbucket/core/servlet/PluginControllerFilter.scala +++ b/src/main/scala/gitbucket/core/servlet/PluginControllerFilter.scala @@ -7,10 +7,10 @@ import gitbucket.core.plugin.PluginRegistry class PluginControllerFilter extends Filter { + private var filterConfig: FilterConfig = null + override def init(filterConfig: FilterConfig): Unit = { - PluginRegistry().getControllers().foreach { case (controller, _) => - controller.init(filterConfig) - } + this.filterConfig = filterConfig } override def destroy(): Unit = { @@ -26,6 +26,9 @@ class PluginControllerFilter extends Filter { } controller.map { case (controller, _) => + if(controller.config == null){ + controller.init(filterConfig) + } controller.doFilter(request, response, chain) }.getOrElse{ chain.doFilter(request, response) diff --git a/src/main/twirl/gitbucket/core/admin/plugins.scala.html b/src/main/twirl/gitbucket/core/admin/plugins.scala.html index 0186e4983..446bdfc29 100644 --- a/src/main/twirl/gitbucket/core/admin/plugins.scala.html +++ b/src/main/twirl/gitbucket/core/admin/plugins.scala.html @@ -1,8 +1,11 @@ -@(plugins: List[gitbucket.core.plugin.PluginInfo])(implicit context: gitbucket.core.controller.Context) +@(plugins: List[gitbucket.core.plugin.PluginInfo], info: Option[Any])(implicit context: gitbucket.core.controller.Context) @gitbucket.core.html.main("Plugins"){ @gitbucket.core.admin.html.menu("plugins") { + @gitbucket.core.helper.html.information(info)

Installed plugins

- +
+ +
@if(plugins.size > 0) {