* configclients.jsp:

- Always show start button for webapps and plugins
    * configclients.jsp, configupdate.jsp:
      - Fix submission when entering CR in a text box
    * Plugins:
      - Stop all plugins at shutdown
      - Log tweaks
    * WebApps:
      - Remove the WAC after stopping it
      - Stop a WAC before starting it to prevent dups
This commit is contained in:
zzz
2010-03-29 21:20:48 +00:00
parent 394903a8f0
commit c43b16cfbb
10 changed files with 102 additions and 24 deletions

View File

@ -11,7 +11,6 @@ import java.util.Set;
import net.i2p.router.startup.ClientAppConfig;
import net.i2p.router.startup.LoadClientAppsJob;
import net.i2p.util.Log;
import org.mortbay.jetty.Server;
@ -19,15 +18,19 @@ import org.mortbay.jetty.Server;
* Saves changes to clients.config or webapps.config
*/
public class ConfigClientsHandler extends FormHandler {
private Log configClient_log;
private Map _settings;
public ConfigClientsHandler() {
configClient_log = ContextHelper.getContext(null).logManager().getLog(ConfigClientsHandler.class);
}
@Override
protected void processForm() {
// set action for when CR is hit in a text input box
if (_action.length() <= 0) {
String url = getJettyString("pluginURL");
if (url != null && url.length() > 0)
_action = "Install Plugin";
else
_action = "Save Client Configuration";
}
if (_action.equals(_("Save Client Configuration"))) {
saveClientChanges();
return;
@ -200,7 +203,7 @@ public class ConfigClientsHandler extends FormHandler {
return;
}
ClientAppConfig ca = clients.get(i);
LoadClientAppsJob.runClient(ca.className, ca.clientName, LoadClientAppsJob.parseArgs(ca.args), configClient_log);
LoadClientAppsJob.runClient(ca.className, ca.clientName, LoadClientAppsJob.parseArgs(ca.args), _log);
addFormNotice(_("Client") + ' ' + _(ca.clientName) + ' ' + _("started") + '.');
}

View File

@ -43,11 +43,11 @@ public class ConfigClientsHelper extends HelperBase {
renderForm(buf, ""+cur, ca.clientName, false, !ca.disabled,
"webConsole".equals(ca.clientName) || "Web console".equals(ca.clientName),
ca.className + ((ca.args != null) ? " " + ca.args : ""), (""+cur).equals(_edit),
true, false, false, true);
true, false, false, true, !ca.disabled);
}
if ("new".equals(_edit))
renderForm(buf, "" + clients.size(), "", false, false, false, "", true, false, false, false, false);
renderForm(buf, "" + clients.size(), "", false, false, false, "", true, false, false, false, false, false);
buf.append("</table>\n");
return buf.toString();
}
@ -65,7 +65,7 @@ public class ConfigClientsHelper extends HelperBase {
String val = props.getProperty(name);
renderForm(buf, app, app, !"addressbook".equals(app),
"true".equals(val), RouterConsoleRunner.ROUTERCONSOLE.equals(app), app + ".war",
false, false, false, false, false);
false, false, false, false, false, true);
}
}
buf.append("</table>\n");
@ -149,7 +149,7 @@ public class ConfigClientsHelper extends HelperBase {
boolean enableStop = !Boolean.valueOf(appProps.getProperty("disableStop")).booleanValue();
renderForm(buf, app, app, false,
"true".equals(val), false, desc.toString(), false, false,
updateURL != null, enableStop, true);
updateURL != null, enableStop, true, true);
}
}
buf.append("</table>\n");
@ -160,7 +160,7 @@ public class ConfigClientsHelper extends HelperBase {
private void renderForm(StringBuilder buf, String index, String name, boolean urlify,
boolean enabled, boolean ro, String desc, boolean edit,
boolean showEditButton, boolean showUpdateButton, boolean showStopButton,
boolean showDeleteButton) {
boolean showDeleteButton, boolean showStartButton) {
buf.append("<tr><td class=\"mediumtags\" align=\"right\" width=\"25%\">");
if (urlify && enabled) {
String link = "/";
@ -183,7 +183,7 @@ public class ConfigClientsHelper extends HelperBase {
buf.append("disabled=\"true\" ");
}
buf.append("></td><td align=\"center\" width=\"15%\">");
if ((!enabled) && !edit) {
if (showStartButton && (!ro) && !edit) {
buf.append("<button type=\"submit\" name=\"action\" value=\"Start ").append(index).append("\" >" + _("Start") + "<span class=hide> ").append(index).append("</span></button>");
}
if (showEditButton && (!edit) && !ro)

View File

@ -35,7 +35,7 @@ import org.mortbay.jetty.Server;
* @author zzz
*/
public class PluginStarter implements Runnable {
private RouterContext _context;
protected RouterContext _context;
static final String PREFIX = "plugin.";
static final String ENABLED = ".startOnLoad";
private static final String[] STANDARD_WEBAPPS = { "i2psnark", "i2ptunnel", "susidns",
@ -223,7 +223,8 @@ public class PluginStarter implements Runnable {
if (name != null && name.length() > 0)
NavHelper.unregisterApp(name);
log.error("Stopping plugin: " + appName);
if (log.shouldLog(Log.WARN))
log.warn("Stopping plugin: " + appName);
return true;
}
@ -426,7 +427,8 @@ public class PluginStarter implements Runnable {
}
try {
addPath(f.toURI().toURL());
log.error("INFO: Adding plugin to classpath: " + f);
if (log.shouldLog(Log.WARN))
log.warn("INFO: Adding plugin to classpath: " + f);
} catch (Exception e) {
log.error("Plugin client " + clientName + " bad classpath element: " + f, e);
}

View File

@ -0,0 +1,40 @@
package net.i2p.router.web;
import net.i2p.router.RouterContext;
import net.i2p.util.Log;
/**
* Stop all plugins that are installed
*
* @since 0.7.13
* @author zzz
*/
public class PluginStopper extends PluginStarter {
public PluginStopper(RouterContext ctx) {
super(ctx);
}
@Override
public void run() {
stopPlugins(_context);
}
/**
* Stop all plugins
* (whether or not they were ever started)
*
* this shouldn't throw anything
*/
static void stopPlugins(RouterContext ctx) {
Log log = ctx.logManager().getLog(PluginStopper.class);
for (String app : getPlugins()) {
try {
stopPlugin(ctx, app);
} catch (Throwable e) {
if (log.shouldLog(Log.WARN))
log.warn("Failed to stop plugin: " + app, e);
}
}
}
}

View File

@ -190,9 +190,11 @@ public class RouterConsoleRunner {
List<RouterContext> contexts = RouterContext.listContexts();
if (contexts != null) {
if (PluginStarter.pluginsEnabled(contexts.get(0))) {
t = new I2PAppThread(new PluginStarter(contexts.get(0)), "PluginStarter", true);
RouterContext ctx = contexts.get(0);
if (PluginStarter.pluginsEnabled(ctx)) {
t = new I2PAppThread(new PluginStarter(ctx), "PluginStarter", true);
t.start();
ctx.addShutdownTask(new PluginStopper(ctx));
}
}
}

View File

@ -43,9 +43,17 @@ public class WebAppStarter {
/**
* add but don't start
* This is used only by RouterConsoleRunner, which adds all the webapps first
* and then starts all at once.
*/
static WebApplicationContext addWebApp(I2PAppContext ctx, Server server, String appName, String warPath, File tmpdir) throws IOException {
// Jetty will happily load one context on top of another without stopping
// the first one, so we remove any previous one here
try {
stopWebApp(server, appName);
} catch (Throwable t) {}
WebApplicationContext wac = server.addWebApplication("/"+ appName, warPath);
tmpdir.mkdir();
wac.setTempDirectory(tmpdir);
@ -64,7 +72,7 @@ public class WebAppStarter {
}
/**
* stop it
* stop it and remove the context
* @throws just about anything, caller would be wise to catch Throwable
*/
static void stopWebApp(Server server, String appName) {
@ -74,6 +82,9 @@ public class WebAppStarter {
// false -> not graceful
wac.stop(false);
} catch (InterruptedException ie) {}
try {
server.removeContext(wac);
} catch (IllegalStateException ise) {}
}
/** see comments in ConfigClientsHandler */

View File

@ -30,7 +30,9 @@ button span.hide{
<% String prev = System.getProperty("net.i2p.router.web.ConfigClientsHandler.nonce");
if (prev != null) System.setProperty("net.i2p.router.web.ConfigClientsHandler.noncePrev", prev);
System.setProperty("net.i2p.router.web.ConfigClientsHandler.nonce", new java.util.Random().nextLong()+""); %>
<input type="hidden" name="nonce" value="<%=System.getProperty("net.i2p.router.web.ConfigClientsHandler.nonce")%>" />
<input type="hidden" name="nonce" value="<%=System.getProperty("net.i2p.router.web.ConfigClientsHandler.nonce")%>" >
<% /* set hidden default */ %>
<button type="submit" name="action" value="" style="display:none" >Cancel</button>
<h3><%=intl._("Client Configuration")%></h3><p>
<%=intl._("The Java clients listed below are started by the router and run in the same JVM.")%>
</p><div class="wideload">

View File

@ -25,7 +25,9 @@
<% String prev = System.getProperty("net.i2p.router.web.ConfigUpdateHandler.nonce");
if (prev != null) System.setProperty("net.i2p.router.web.ConfigUpdateHandler.noncePrev", prev);
System.setProperty("net.i2p.router.web.ConfigUpdateHandler.nonce", new java.util.Random().nextLong()+""); %>
<input type="hidden" name="nonce" value="<%=System.getProperty("net.i2p.router.web.ConfigUpdateHandler.nonce")%>" />
<input type="hidden" name="nonce" value="<%=System.getProperty("net.i2p.router.web.ConfigUpdateHandler.nonce")%>" >
<% /* set hidden default */ %>
<input type="submit" name="action" value="" style="display:none" >
<h3><%=intl._("Check for I2P and news updates")%></h3>
<div class="wideload"><table border="0" cellspacing="5">
<tr><td colspan="2"></tr>
@ -59,6 +61,6 @@
<% } // if canInstall %>
<tr class="tablefooter"><td colspan="2">
<div class="formaction">
<input type="submit" name="action" value="<%=intl._("Save")%>" />
<input type="reset" value="<%=intl._("Cancel")%>" />
<input type="reset" value="<%=intl._("Cancel")%>" >
<input type="submit" name="action" value="<%=intl._("Save")%>" >
</div></td></tr></table></div></form></div></div></body></html>

View File

@ -1,3 +1,19 @@
2010-03-29 zzz
* configclients.jsp:
- Always show start button for webapps and plugins
* configclients.jsp, configupdate.jsp:
- Fix submission when entering CR in a text box
* EepGet: Don't retry after a MalformedURLException
* HTTPResponseOutputStream: More static
* Plugins:
- Stop all plugins at shutdown
- Log tweaks
* WebApps:
- Remove the WAC after stopping it
- Stop a WAC before starting it to prevent dups
- Implement destroy() in addressbook to prevent dups
- Implement destroy() in i2psnark to prevent dups
2010-03-25 zzz
* configclients.jsp: Fix dup anchor
* Console: Sort plugin links in summary bar

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */
public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 2;
public final static long BUILD = 3;
/** for example "-test" */
public final static String EXTRA = "";