* 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.ClientAppConfig;
import net.i2p.router.startup.LoadClientAppsJob; import net.i2p.router.startup.LoadClientAppsJob;
import net.i2p.util.Log;
import org.mortbay.jetty.Server; import org.mortbay.jetty.Server;
@ -19,15 +18,19 @@ import org.mortbay.jetty.Server;
* Saves changes to clients.config or webapps.config * Saves changes to clients.config or webapps.config
*/ */
public class ConfigClientsHandler extends FormHandler { public class ConfigClientsHandler extends FormHandler {
private Log configClient_log;
private Map _settings; private Map _settings;
public ConfigClientsHandler() {
configClient_log = ContextHelper.getContext(null).logManager().getLog(ConfigClientsHandler.class);
}
@Override @Override
protected void processForm() { 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"))) { if (_action.equals(_("Save Client Configuration"))) {
saveClientChanges(); saveClientChanges();
return; return;
@ -200,7 +203,7 @@ public class ConfigClientsHandler extends FormHandler {
return; return;
} }
ClientAppConfig ca = clients.get(i); 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") + '.'); addFormNotice(_("Client") + ' ' + _(ca.clientName) + ' ' + _("started") + '.');
} }

View File

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

View File

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

View File

@ -43,9 +43,17 @@ public class WebAppStarter {
/** /**
* add but don't start * 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 { 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); WebApplicationContext wac = server.addWebApplication("/"+ appName, warPath);
tmpdir.mkdir(); tmpdir.mkdir();
wac.setTempDirectory(tmpdir); 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 * @throws just about anything, caller would be wise to catch Throwable
*/ */
static void stopWebApp(Server server, String appName) { static void stopWebApp(Server server, String appName) {
@ -74,6 +82,9 @@ public class WebAppStarter {
// false -> not graceful // false -> not graceful
wac.stop(false); wac.stop(false);
} catch (InterruptedException ie) {} } catch (InterruptedException ie) {}
try {
server.removeContext(wac);
} catch (IllegalStateException ise) {}
} }
/** see comments in ConfigClientsHandler */ /** see comments in ConfigClientsHandler */

View File

@ -30,7 +30,9 @@ button span.hide{
<% String prev = System.getProperty("net.i2p.router.web.ConfigClientsHandler.nonce"); <% String prev = System.getProperty("net.i2p.router.web.ConfigClientsHandler.nonce");
if (prev != null) System.setProperty("net.i2p.router.web.ConfigClientsHandler.noncePrev", prev); 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()+""); %> 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> <h3><%=intl._("Client Configuration")%></h3><p>
<%=intl._("The Java clients listed below are started by the router and run in the same JVM.")%> <%=intl._("The Java clients listed below are started by the router and run in the same JVM.")%>
</p><div class="wideload"> </p><div class="wideload">

View File

@ -25,7 +25,9 @@
<% String prev = System.getProperty("net.i2p.router.web.ConfigUpdateHandler.nonce"); <% String prev = System.getProperty("net.i2p.router.web.ConfigUpdateHandler.nonce");
if (prev != null) System.setProperty("net.i2p.router.web.ConfigUpdateHandler.noncePrev", prev); 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()+""); %> 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> <h3><%=intl._("Check for I2P and news updates")%></h3>
<div class="wideload"><table border="0" cellspacing="5"> <div class="wideload"><table border="0" cellspacing="5">
<tr><td colspan="2"></tr> <tr><td colspan="2"></tr>
@ -59,6 +61,6 @@
<% } // if canInstall %> <% } // if canInstall %>
<tr class="tablefooter"><td colspan="2"> <tr class="tablefooter"><td colspan="2">
<div class="formaction"> <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> </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 2010-03-25 zzz
* configclients.jsp: Fix dup anchor * configclients.jsp: Fix dup anchor
* Console: Sort plugin links in summary bar * Console: Sort plugin links in summary bar

View File

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