Commit 10602445 authored by daryl herzmann's avatar daryl herzmann Committed by GitHub

Merge pull request #655 from guusdk/Plugin-fixes

Plugin fixes
parents 771bbab3 fb589eba
......@@ -2585,14 +2585,14 @@ plugin.admin.info=Plugins add new functionality to the server. The list of plugi
<a href="available-plugins.jsp">Available Plugins</a> page.
plugin.admin.deleted_success=Plugin deleted successfully.
plugin.admin.deleted_failure=Unable to delete plugin.
plugin.admin.uploaded_success=Plugin uploaded successfully. It may take a short time for the \
plugin to appear in the list of installed plugins.
plugin.admin.uploaded_success=Plugin uploaded successfully.
plugin.admin.uploaded_failure=Unable to upload plugin. See server error logs.
plugin.admin.upload_plugin=Upload Plugin
plugin.admin.upload_plugin.info=Plugin files (.jar) can be uploaded directly by using the form below.
plugin.admin.click_reload=Reload the plugin.
plugin.admin.reload_success=Plugin was successfully reloaded. It may take a short time for the \
plugin to appear in the list of installed plugins again.
plugin.admin.reload_success=Plugin was successfully reloaded.
plugin.admin.reload_failure=Unable to reload the plugin. Refer to the log files for additional information.
plugin.admin.monitortask_running=The plugin manager is currently running. It may take a short time for the list of installed plugins to be complete.
plugin.admin.name=Plugins
plugin.admin.description=Description
plugin.admin.version=Version
......
......@@ -39,6 +39,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
......@@ -580,6 +581,38 @@ public class PluginManager
}
}
public boolean reloadPlugin( String pluginName )
{
Log.debug( "Reloading plugin '{}'..." );
final Plugin plugin = getPlugin( pluginName );
if ( plugin == null )
{
Log.warn( "Unable to reload plugin '{}'. No such plugin loaded.", pluginName );
return false;
}
final Path path = getPluginPath( plugin );
if ( path == null )
{
// When there's a plugin, there should be a path. If there isn't, our code is buggy.
throw new IllegalStateException( "Unable to determine installation path of plugin: " + pluginName );
}
try
{
Files.setLastModifiedTime( path, FileTime.fromMillis( 0 ) );
}
catch ( IOException e )
{
Log.warn( "Unable to reload plugin '{}'. Unable to reset the 'last modified time' of the plugin path. Try removing and restoring the plugin jar file manually." );
return false;
}
pluginMonitor.runNow( false );
return true;
}
/**
* Unloads a plugin. The {@link Plugin#destroyPlugin()} method will be called and then any resources will be
* released. The name should be the canonical name of the plugin (based on the plugin directory name) and not the
......@@ -594,7 +627,7 @@ public class PluginManager
*
* @param pluginName the name of the plugin to unload.
*/
public void unloadPlugin( String pluginName )
void unloadPlugin( String pluginName )
{
Log.debug( "Unloading plugin '{}'...", pluginName );
......@@ -609,15 +642,14 @@ public class PluginManager
// See if any child plugins are defined.
if ( parentPluginMap.containsKey( plugin ) )
{
String[] childPlugins =
parentPluginMap.get( plugin ).toArray( new String[ parentPluginMap.get( plugin ).size() ] );
parentPluginMap.remove( plugin );
String[] childPlugins = parentPluginMap.get( plugin ).toArray( new String[ parentPluginMap.get( plugin ).size() ] );
for ( String childPlugin : childPlugins )
{
Log.debug( "Unloading child plugin: '{}'.", childPlugin );
childPluginMap.remove( plugins.get( childPlugin ) );
unloadPlugin( childPlugin );
}
parentPluginMap.remove( plugin );
}
Path webXML = pluginDirectory.resolve( pluginName ).resolve( "web" ).resolve( "WEB-INF" ).resolve( "web.xml" );
......@@ -1015,4 +1047,9 @@ public class PluginManager
}
}
}
public boolean isMonitorTaskRunning()
{
return pluginMonitor.isTaskRunning();
}
}
\ No newline at end of file
......@@ -45,6 +45,8 @@ public class PluginMonitor
private ScheduledExecutorService executor;
private boolean isTaskRunning = false;
public PluginMonitor( final PluginManager pluginManager )
{
this.pluginManager = pluginManager;
......@@ -84,6 +86,11 @@ public class PluginMonitor
}
}
public boolean isTaskRunning()
{
return isTaskRunning;
}
/**
* Immediately run a check of the plugin directory.
*/
......@@ -111,6 +118,7 @@ public class PluginMonitor
// Prevent two tasks from running in parallel by using the plugin monitor itself as a mutex.
synchronized ( PluginMonitor.this )
{
isTaskRunning = true;
try
{
// The directory that contains all plugins.
......@@ -319,6 +327,10 @@ public class PluginMonitor
{
Log.error( "An unexpected exception occurred:", e );
}
finally
{
isTaskRunning = false;
}
}
}
......
......@@ -44,6 +44,12 @@
REST API Plugin Changelog
</h1>
<p><b>1.2.5</b> -- October 14th, 2016</p>
<ul>
<li>Updated to match new API in Openfire 4.1.0</li>
<li>Requires Openfire 4.1.0 or later.</li>
</ul>
<p><b>1.2.4</b> -- July 4th, 2016</p>
<ul>
<li>Fixed: Send a presence by affiliation change</li>
......
......@@ -5,9 +5,9 @@
<name>REST API</name>
<description>Allows administration over a RESTful API.</description>
<author>Roman Soldatow</author>
<version>1.2.4</version>
<date>07/04/2016</date>
<minServerVersion>4.0.0</minServerVersion>
<version>1.2.5</version>
<date>10/14/2016</date>
<minServerVersion>4.1.0</minServerVersion>
<adminconsole>
<tab id="tab-server">
<sidebar id="sidebar-server-settings">
......
......@@ -55,7 +55,7 @@
if(is2Reload) {
String pluginName = pluginManager.getName(plugin);
String pluginDir = pluginManager.getPluginDirectory(plugin).getName();
pluginManager.unloadPlugin(pluginDir);
pluginManager.reloadPlugin(pluginDir);
// Log the event
admin.logEvent("reloaded plugin "+ pluginName, null);
......
......@@ -37,8 +37,10 @@
<%@ page import="org.apache.commons.fileupload.FileItem" %>
<%@ page import="org.apache.commons.fileupload.FileUploadException" %>
<%@ taglib uri="admin" prefix="admin" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<jsp:useBean id="webManager" class="org.jivesoftware.util.WebManager" />
<% webManager.init(request, response, session, application, out ); %>
......@@ -96,7 +98,7 @@
for (Plugin plugin : plugins) {
File pluginDir = pluginManager.getPluginDirectory(plugin);
if (reloadPlugin.equals(pluginDir.getName())) {
pluginManager.unloadPlugin(reloadPlugin);
pluginManager.reloadPlugin(reloadPlugin);
// Log the event
webManager.logEvent("reloaded plugin "+reloadPlugin, null);
response.sendRedirect("plugin-admin.jsp?reloadsuccess=true");
......@@ -421,51 +423,42 @@
</head>
<body>
<% if ("true".equals(request.getParameter("deletesuccess"))) { %>
<div class="success">
<fmt:message key="plugin.admin.deleted_success"/>
</div>
<br>
<% }
else if ("false".equals(request.getParameter("deletesuccess"))) { %>
<div class="error">
<fmt:message key="plugin.admin.deleted_failure"/>
</div>
<br>
<% } %>
<% if ("true".equals(request.getParameter("reloadsuccess"))) { %>
<div class="success">
<fmt:message key="plugin.admin.reload_success"/>
</div>
<br>
<% } %>
<% if ("true".equals(request.getParameter("uploadsuccess"))) { %>
<div class="success">
<fmt:message key="plugin.admin.uploaded_success"/>
</div>
<br>
<% }
else if ("false".equals(request.getParameter("uploadsuccess"))) { %>
<div class="error">
<fmt:message key="plugin.admin.uploaded_failure"/>
</div>
<br>
<% } %>
<p>
<c:if test="${param.deletesuccess eq 'true'}">
<admin:infobox type="success">
<fmt:message key="plugin.admin.deleted_success" />
</admin:infobox>
</c:if>
<c:if test="${param.deletesuccess eq 'false'}">
<admin:infobox type="error">
<fmt:message key="plugin.admin.deleted_failure" />
</admin:infobox>
</c:if>
<c:if test="${param.reloadsuccess eq 'true'}">
<admin:infobox type="success">
<fmt:message key="plugin.admin.reload_success" />
</admin:infobox>
</c:if>
<c:if test="${param.reloadsuccess eq 'false'}">
<admin:infobox type="success">
<fmt:message key="plugin.admin.reload_failure" />
</admin:infobox>
</c:if>
<c:if test="${param.uploadsuccess eq 'true'}">
<admin:infobox type="success">
<fmt:message key="plugin.admin.uploaded_success" />
</admin:infobox>
</c:if>
<c:if test="${param.uploadsuccess eq 'false'}">
<admin:infobox type="error">
<fmt:message key="plugin.admin.uploaded_failure" />
</admin:infobox>
</c:if>
<c:if test="${ webManager.XMPPServer.pluginManager.monitorTaskRunning }">
<admin:infobox type="info">
<fmt:message key="plugin.admin.monitortask_running" />
</admin:infobox>
</c:if>
<p>
<fmt:message key="plugin.admin.info"/>
</p>
......@@ -557,7 +550,7 @@ else if ("false".equals(request.getParameter("uploadsuccess"))) { %>
<%= pluginAuthor != null ? pluginAuthor : "" %> &nbsp;
</td>
<td width="1%" align="center" valign="top" class="<%= update != null ? "update-top" : "line-bottom-border"%>">
<a href="plugin-admin.jsp?reloadplugin=<%= dirName %>"
<a href="plugin-admin.jsp?csrf=${csrf}&reloadplugin=<%= dirName %>"
title="<fmt:message key="plugin.admin.click_reload" />"
><img src="images/refresh-16x16.gif" width="16" height="16" border="0" alt="<fmt:message key="global.refresh" />"></a>
</td>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment